def itensidade(img, value, option=True): ''' Inputs: - img = Imagem BGR; - value = valor de ajuste de intensidade; - option = True: aumentar False: diminuir Output: Salva imagem no diretório ''' if len(img.shape) > 2: hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) else: img2 = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) hsv = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) if (option == True): lim = 255 - value s[s > lim] = 255 s[s <= lim] += value i = 'aumentou' elif (option == False): lim = 0 + value s[s < lim] = 0 s[s >= lim] -= value i = 'diminuiu' final_hsv = cv2.merge((h, s, v)) img2 = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR) viewImage(img2, 'Intensidade %s em %d' % (i, value)) return saveChanges(img, img2)
def sobel(img): #recebe a dimensao da mascara kernel = 0 print() while(kernel is not 3 and kernel is not 5 and kernel is not 7): kernel = int(input('Tamanho do filtro? (3 ou 5 ou 7, apenas) : ')) if kernel is not 3 and kernel is not 5 and kernel is not 7 : print('ERRO: O tamanho do filtro deve ser 3, 5 ou 7!') # converte a imagem para cinza, se ela ja não for if len(img.shape) > 2: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: gray = img # aplica o filtro sobel nas direcoes x e y grad_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=kernel) grad_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=kernel) # o resultado de cada mascara do filtro possui valores float # pega o valor absoluto dos pixels resultantes do gradiente na direcao x e y abs_grad_x = cv2.convertScaleAbs(grad_x) abs_grad_y = cv2.convertScaleAbs(grad_y) # cv2.addWeighted(src1, alpha, src2, beta, gamma) -> src1 * alpha + src2 * beta + gamma # faz a soma dos grdientes x e y grad = cv2.addWeighted(grad_x, 0.5, grad_y, 0.5, 0) # gradiente com valores float. Os valores são deslocados para serem 8b grad_trunc = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0) # gradiente com valores absolutos # exibe as imagens lab1.viewImages([img, grad_trunc, grad], ['Imagem original', 'Sobel valores absolutos', 'Sobel valores deslocados']) return saveChanges(img,grad_trunc)
def brightness(img, value, option=True): ''' Inputs: - img = Imagem BGR; - value = valor de ajuste de brilho; - option = True: aumentar de brilho False: diminuir brilho. Output: Salva imagem no diretório ''' if len(img.shape) > 2: hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) else: img2 = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) hsv = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) if (option == True): lim = 255 - value v[v > lim] = 255 v[v <= lim] += value b = 'aumentou' elif (option == False): lim = 0 + value v[v < lim] = 0 v[v >= lim] -= value b = 'diminuiu' final_hsv = cv2.merge((h, s, v)) img2 = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR) #cv2.imwrite("image_processed.jpg", img) viewImage(img2, 'Brilho %s em %d' % (b, value)) return saveChanges(img, img2)
def subamostragem(image, amostra=2): if len(image.shape) > 2: image2 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) #a imagem vem em formato BGR new_shape = (int((image2.shape[0] + 0.5) / amostra), int((image2.shape[1] + 0.5) / amostra), image2.shape[2] ) #divide a imagem em 1/4 img_sub = np.zeros((new_shape[0], new_shape[1], new_shape[2]), np.uint8) for x in range(new_shape[0]): for y in range(new_shape[1]): for z in range(new_shape[2]): img_sub[x][y][z] = image2[(x * amostra)][(y * amostra)][z] img_sub = cv2.cvtColor(img_sub, cv2.COLOR_RGB2BGR) else: new_shape = (int((image.shape[0] + 0.5) / amostra), int((image.shape[1] + 0.5) / amostra) ) #divide a imagem em 1/4 #print("new shape: ", new_shape) img_sub = np.zeros((new_shape[0], new_shape[1]), np.uint8) #print(img_bin.shape) for x in range(new_shape[0]): for y in range(new_shape[1]): img_sub[x][y] = int(image[(x * amostra)][(y * amostra)]) viewImage( img_sub, 'Subamostragem em %d, dimensões: %dx%d' % (amostra, new_shape[0], new_shape[1])) return saveChanges(image, img_sub)
def prewitt(image): # converte a imagem para cinza, se ela ja não for if len(image.shape) > 2: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray = image # cria as máscaras kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=np.float32) kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=np.float32) # aplica o filtro prewitt nas direcoes x e y grad_x = cv2.filter2D(gray, -1, kernelx) grad_y = cv2.filter2D(gray, -1, kernely) # o resultado de cada mascara do filtro possui valores float # pega o valor absoluto dos pixels resultantes do gradiente na direcao x e y abs_grad_x = cv2.convertScaleAbs(grad_x) abs_grad_y = cv2.convertScaleAbs(grad_y) # cv2.addWeighted(src1, alpha, src2, beta, gamma) -> src1 * alpha + src2 * beta + gamma # faz a soma dos grdientes x e y grad = cv2.addWeighted( grad_x, 0.5, grad_y, 0.5, 0 ) # gradiente com valores float. Os valores são deslocados para serem 8b # exibe as imagens lab1.viewImages([image, grad], ['Imagem original', 'Prewitt valores absolutos']) return saveChanges(image, grad)
def dilatar(image, mask, tipo): kernel = None while (tipo < 0 or tipo > 2): if tipo == 0: # Rectangular Kernel kernel = cv2.getStructuringElement(cv2.MORPH_RECT, mask) elif tipo == 1: # Elliptical Kernel kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, mask) elif tipo == 2: # Cross-shaped Kernel kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, mask) else: print("Tipo inválido !") tipo = int( input( "Qual o formato da máscara? 0: retangular; 1: elíptica; 2:cruz. \n -->" )) dilation = cv2.dilate(image, kernel, iterations=1) title = ( 'original x dilatacao [clique nesta janela e aperte uma tecla para sair]' ) compare = np.concatenate((image, dilation), axis=1) cv2.imshow(title, compare) cv2.waitKey(0) cv2.destroyAllWindows() return saveChanges(image, dilation)
def negative(image): ''' Input: imagem BGR Output: None ''' if len(image.shape) > 2: #separa as componentes RGB B, G, R = cv2.split(image) #inverte cada componente B_neg = 255 - B G_neg = 255 - G R_neg = 255 - R #merge das componentes im_neg = cv2.merge([B_neg, G_neg, R_neg]) # converte para escala de cinza im_neg_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # inverte im_neg_gray = 255 - im_neg_gray # exibe as imagens lab1.viewImages([im_neg, im_neg_gray], ['Imagem Negativa', 'Imagem negativa Escala de Cinza']) else: im_neg = 255 - image # inverte lab1.viewImage(im_neg, 'imagem negativa') # exibe a imagem return saveChanges(image, im_neg)
def descontinuidade(image): ####################### #Entradas # - Imagem # - Limiar ####################### limiar = int(input("Informe o valor (positivo) do limiar: ")) #converte a imagem para a escala de cinza se for colorida if len(image.shape) > 2: image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #aplica o Filtro Laplaciano image_laplaciano = cv2.Laplacian(image_gray, cv2.CV_64F, 3) #converte para unsigned int de 8 bits image_laplaciano = np.uint8(np.absolute(image_laplaciano)) #realiza a limiarização lim, img_limiar = cv2.threshold(image_laplaciano, limiar, 255, cv2.THRESH_BINARY) lab1.viewImages([image, image_laplaciano, img_limiar], ['Imagem original', 'Filtro Laplaciano', 'Limiarização']) return saveChanges(image, image_laplaciano, img_limiar)
def houghLinhas(image, threshold): ################# #Entradas # - Imagem # - Limiar ################# img = np.copy(image) #Detecção das bordas usando detector Canny edges = cv2.Canny(image, 50, 200, apertureSize=3) #Aplicação da transformada # - Saída do detector de bordas # - Parametro rô (rho) # - Parametro teta (theta) # - Limiar lines = cv2.HoughLines(edges, 1, np.pi / 180, threshold) #Desenhando linhas encontradas for i in range(0, len(lines)): rho = lines[i][0][0] theta = lines[i][0][1] a = math.cos(theta) b = math.sin(theta) x0 = a * rho y0 = b * rho pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * (a))) pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * (a))) cv2.line(image, pt1, pt2, (0, 0, 255), 3, cv2.LINE_AA) #visualizacao do resultado lab1.viewImages([img, image], ['Imagem original', 'Transformada de Hough']) return saveChanges(img, image)
def calcMaskMedianaUnico(img): mascara = int(input("Qual a mascara? ex.: 3 ou 5 ou 7 - APENAS valor ímpar > 3. \n --> ")) #img = cv2.imread(image_name) mediana = cv2.medianBlur(img, mascara) compare = np.concatenate((img, mediana),axis=1) #side by side comparison title = ('original x mascara de mediana %d' %mascara) cv2.imshow(title , compare) cv2.waitKey(0) cv2.destroyAllWindows() return saveChanges(img, mediana)
def kmeans(image, gray, K): ####################### #Entradas # - Imagem # - Aplicar tons de cinza (sim ou não) # - Numero de clusters ####################### #Conversao para tons de cinza if gray == True: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) Z = image.reshape((-1, 3)) #Conversao para float32 Z = np.float32(Z) #Definicao do criterio # - Tupla com: # - tipo # . - TERM_CRITERIA_EPS # . pare se a precisão for atingida. # . # . - TERM_CRITERIA_MAX_ITER # . pare se número maximo de iterações for atingido. # . # - maximo de iteracaoes # - precisão criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) #Aplicacao do Kmeans # - Entrada # - Numero de clusters # - Melhores labels # - Criterio # - Iteracoes # - Definicao dos centros iniciais # # Output # - distance: soma da distância ao quadrado de cada ponto # até seus centros correspondentes. # - label: vetor de labels # - center: vetor de centros dos clusters distance, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) #Conversao para uint8 novamente center = np.uint8(center) #Obtendo imagem de saida output = center[label.flatten()].reshape((image.shape)) lab1.viewImages([image, output], ['Imagem de entrada', 'Kmeans']) return saveChanges(image, output)
def houghCirculos(image, minRadius, maxRadius): ################# #Entradas # - Imagem # - Raio minimo # - Raio maximo ################# output = np.copy(image) #escala de cinza gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #suavizacao para reduzir ruido e #diminuir deteccao de ciruculos falsos gray = cv2.medianBlur(gray, 5) rows = gray.shape[0] #Aplicação da transformada # - Imagem em tonsde cinza # - Metodo de deteccao # - # - Distancia minima entre os centros # - Limiar superior # - Limiar para detecacao de centro # - Raio minimo # - Raio maximo circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, rows / 8, param1=100, param2=30, minRadius=minRadius, maxRadius=maxRadius) #Desenhando circulos encontrados if circles is not None: circles = np.uint16(np.around(circles)) for i in circles[0, :]: center = (i[0], i[1]) # circle center cv2.circle(output, center, 1, (0, 100, 100), 3) # circle outline radius = i[2] cv2.circle(output, center, radius, (255, 0, 255), 3) #visualizacao do resultado lab1.viewImages([image, output], ['Imagem original', 'Transformada de Hough']) return saveChanges(image, output)
def trans_potencia(image): original = image c = 1 gamma = 2.5 altura = original.shape[0] largura = original.shape[1] #se a imagem for RGB if len(original.shape) > 2: dimensoes = original.shape[2] #matriz de saída image = np.zeros((altura, largura, dimensoes), dtype=np.float32) #percorrendo a imagem para aplicacao da formula for i in range(altura): for j in range(largura): for k in range(dimensoes): image[i, j, k] = c * math.pow(original[i, j, k], gamma) #caso, contrário else: image = np.zeros((altura, largura, 1), dtype=np.float32) for i in range(altura): for j in range(largura): image[i, j] = c * math.pow(original[i, j], gamma) #normalizacao da imagem [0,255] cv2.normalize(image, image, 0, 255, cv2.NORM_MINMAX) image = cv2.convertScaleAbs(image) # plota imagens e histogramas f = plt.figure() f.add_subplot(2, 2, 1) plt.title('Imagem original') plt.imshow(cv2.cvtColor(original, cv2.COLOR_BGR2RGB)) f.add_subplot(2, 2, 2) plt.title('Imagem transformada') plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) f.add_subplot(2, 2, 3) plt.title('Histograma da imagem original') plt.plot(cv2.calcHist([original], [0], None, [256], [0, 255])) f.add_subplot(2, 2, 4) plt.title('Histograma da imagem transformada') plt.plot(cv2.calcHist([image], [0], None, [256], [0, 255])) plt.show() return saveChanges(original, image)
def bilateral(image): ''' Input: image ''' diametro = int(input("Entre com o diâmetro: ")) sigma_color = float(input("Entre com o valor sigmaColor: ")) sigma_space = float(input("Entre com o valor sigmaSpace: ")) # aplica filtro bilat = cv2.bilateralFilter(image, diametro, sigma_color, sigma_space) lab1.viewImages([image, bilat], ['Imagem original', 'Filtro Bilateral']) return saveChanges(image, bilat)
def filterGaussian(img): ''' Input: img - imagem; sigmaX - desvio padrão na direção x sigmaY - desvio padrão na direção y Obs.: Se apenas o sigmaX for especificado, o sigmaY será considerado igual ao sigmaX. Pelo menos o sigmaX deve, obrigatoriamente, ser especificado. Output: None ''' print() #recebe a dimensao da mascara mascara = int(input("Qual a mascara? ex.: 3 ou 5 ou 7 - APENAS valor ímpar > 3. \n --> ")) #opções de desvio option = int(input(""" 1: Entrar com desvio de X e Y 2: Entrar apenas com desvio de X Opção: """)) if(option == 1): stdX = float(input("Qualo valor do desvio padrão de X ? ")) stdY = float(input("Qualo valor do desvio padrão de Y ? ")) #aplica a filtragem gaussiana gaussian = cv2.GaussianBlur(img,(mascara,mascara),stdX, stdY) elif(option == 2): stdX = int(input("Qualo valor do desvio padrão de X ? ")) #aplica a filtragem gaussiana gaussian = cv2.GaussianBlur(img,(mascara,mascara),stdX) ''' #concatena a imagem original com a imagem que passou pelo processo de filtragem compare = np.concatenate((img, gaussian),axis=1) #define titulo da imagem title = ('Imagem original x Imagem apos Filtro Gaussiano %d' %mascara) #plot image cv2.imshow(title , compare) cv2.waitKey(0) cv2.destroyAllWindows() ''' lab1.viewImages([img, gaussian], ['Imagem original', 'Imagem apos Filtro Gaussiano %f' %mascara]) return saveChanges(img, gaussian)
def canny(image): ''' Input: image ''' lowThreshold = float(input("Entre com o valor de lowThreshold: ")) highThreshold = float(input("Entre com o valor de highThreshold: ")) # converte a imagem para cinza, se ela ja não for if len(image.shape) > 2: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray = image # aplica filtro canny = cv2.Canny(gray, lowThreshold, highThreshold) lab1.viewImages([image, canny], ['Imagem original', 'Canny']) return saveChanges(image, canny)
def binarizar(image, limiar=128): #Binarização da imagem if len(image.shape) > 2: image2 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: image2 = image img_bin = np.zeros(image2.shape, np.uint8) #passa a dimensão y (sao invertidos), mas aqui usa-se o x por convencao for x in range(img_bin.shape[0]): for y in range(img_bin.shape[1]): #print(img_gray[x][y]) if image2[x][y] <= limiar: img_bin[x][y] = 0 #ausência de cor é preto (baixa cor) else: img_bin[x][y] = 255 #muita cor, branco viewImage(img_bin, 'Imagem binarizada em %d' % limiar) return saveChanges(image, img_bin)
def trans_intensidade_gray(image, a=80, b=160, alfa=40, beta=10, charlie=-30): original = image if len(image.shape) > 2: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) for i in range(image.shape[0]): for j in range(image.shape[1]): if image[i][j] < a: image[i][j] = image[i][j] + alfa elif image[i][j] > a and image[i][j] < b: image[i][j] = image[i][j] + beta else: image[i][j] = image[i][j] + charlie #plt.imshow(image, cmap='gray') # plota imagens e histogramas f = plt.figure() f.add_subplot(2, 2, 1) plt.title('Imagem original') plt.imshow(cv2.cvtColor(original, cv2.COLOR_BGR2RGB)) f.add_subplot(2, 2, 2) plt.title('Imagem transformada') plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) f.add_subplot(2, 2, 3) plt.title('Histograma da imagem original') plt.plot(cv2.calcHist([original], [0], None, [256], [0, 255])) f.add_subplot(2, 2, 4) plt.title('Histograma da imagem transformada') plt.plot(cv2.calcHist([image], [0], None, [256], [0, 255])) plt.show() return saveChanges(original, image)
def laplaciano(img): #se imagem for colorida, converte para escala gray if len(img.shape) > 2: imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #aplica o filtro kernel = 3 #dimensoes da mascara resultado3 = cv2.Laplacian(imgGray, cv2.CV_64F, ksize=kernel) #converte para unsigned int de 8 bits resultado3 = np.uint8(np.absolute(resultado3)) #aplica o filtro kernel = 5 resultado5 = cv2.Laplacian(imgGray, cv2.CV_64F, ksize=kernel) #converte para unsigned int de 8 bits resultado5 = np.uint8(np.absolute(resultado5)) #aplica o filtro kernel = 7 resultado7 = cv2.Laplacian(imgGray, cv2.CV_64F, ksize=kernel) #converte para unsigned int de 8 bits resultado7 = np.uint8(np.absolute(resultado7)) #exibe a imagem original e a resultado lab1.viewImages([imgGray, resultado3,resultado5, resultado7], ['Imagem(gray)', 'Laplaciano 3x3', 'Laplaciano 5x5', 'Laplaciano 7x7']) #empilha as imagens resultado images = np.vstack([resultado3,resultado5, resultado7]) return saveChanges(img,images)
def equalizeHist(image): if len(image.shape) < 3: print('Essa opção só é válida para imagens coloridas') print('<Pressione ENTER para continuar>') input() return image #Separa as componentes da imagem colorida B, G, R = cv2.split(image) #Equalizando cada componente separadamente B_eq = cv2.equalizeHist(B) G_eq = cv2.equalizeHist(G) R_eq = cv2.equalizeHist(R) #uni as componentes image_eq = cv2.merge([B_eq, G_eq, R_eq]) # plota imagens e histogramas f = plt.figure() f.add_subplot(2, 2, 1) plt.title('Imagem original') plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) f.add_subplot(2, 2, 2) plt.title('Imagem equalizada') plt.imshow(cv2.cvtColor(image_eq, cv2.COLOR_BGR2RGB)) f.add_subplot(2, 1, 2) plt.title('Histograma') plt.plot(cv2.calcHist([image_eq], [0], None, [256], [0, 255]), color='gray') plt.show() return saveChanges(image, image_eq)
def kirsch(image): # converte a imagem para cinza, se ela ja não for if len(image.shape) > 2: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray = image # cria as 8 máscaras kernelG1 = np.array([[5, -3, -3], [5, 0, -3], [5, -3, -3]], dtype=np.float32) kernelG2 = np.array([[-3, -3, -3], [5, 0, -3], [5, 5, -3]], dtype=np.float32) kernelG3 = np.array([[-3, -3, -3], [-3, 0, -3], [5, 5, 5]], dtype=np.float32) kernelG4 = np.array([[-3, -3, -3], [-3, 0, 5], [-3, 5, 5]], dtype=np.float32) kernelG5 = np.array([[-3, -3, 5], [-3, 0, 5], [-3, -3, 5]], dtype=np.float32) kernelG6 = np.array([[-3, 5, 5], [-3, 0, 5], [-3, -3, -3]], dtype=np.float32) kernelG7 = np.array([[5, 5, 5], [-3, 0, -3], [-3, -3, -3]], dtype=np.float32) kernelG8 = np.array([[5, 5, -3], [5, 0, -3], [-3, -3, -3]], dtype=np.float32) # aplica as 8 máscaras do filtro kirsc norm = cv2.NORM_MINMAX g1 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG1), None, 0, 255, norm, cv2.CV_8UC1) g2 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG2), None, 0, 255, norm, cv2.CV_8UC1) g3 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG3), None, 0, 255, norm, cv2.CV_8UC1) g4 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG4), None, 0, 255, norm, cv2.CV_8UC1) g5 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG5), None, 0, 255, norm, cv2.CV_8UC1) g6 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG6), None, 0, 255, norm, cv2.CV_8UC1) g7 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG7), None, 0, 255, norm, cv2.CV_8UC1) g8 = cv2.normalize(cv2.filter2D(gray, cv2.CV_32F, kernelG8), None, 0, 255, norm, cv2.CV_8UC1) # pega os valores máximos de cada resultado grad = cv2.max(g1, g2) grad = cv2.max(grad, g3) grad = cv2.max(grad, g4) grad = cv2.max(grad, g5) grad = cv2.max(grad, g6) grad = cv2.max(grad, g7) grad = cv2.max(grad, g8) # exibe as imagens lab1.viewImages([image, grad], ['Imagem original', 'Kirsch valores absolutos']) return saveChanges(image, grad)
def equalizeHist_gray(image): original = image if len(image.shape) > 2: print('Essa opção só é válida para imagens em tons de cinza') print('<Pressione ENTER para continuar>') input() return image # probabilidade p = np.zeros(256) # esse v_min é a intensidade mínima em cada canal de cor v_min = [ 256 ] # o valor real (da formula) de v_min é vr[v_min[0]], por exemplo # probabilidade acumulada v = np.zeros(256) # calcula valores de p e v_min h, w = image.shape for x in range(w): for y in range(h): if image[y, x] < v_min: v_min = image[y, x] p[image[y, x]] += 1 # calcula valores de v v[0] = p[0] / (w * h) for i in range(255): i += 1 v[i] = v[i - 1] + p[i] / (w * h) # atualiza os valores da imagem (valores v*) for x in range(w): for y in range(h): image[y, x] = int((v[image[y, x]] - v[v_min]) / (1 - v[v_min]) * 255 + 0.5) # plota imagens e histogramas f = plt.figure() f.add_subplot(2, 2, 1) plt.title('Imagem original') plt.imshow(original, cmap='gray') f.add_subplot(2, 2, 2) plt.title('Imagem equalizada') plt.imshow(image, cmap='gray') f.add_subplot(2, 1, 2) plt.title('Histograma') plt.plot(cv2.calcHist([image], [0], None, [256], [0, 255]), color='gray') plt.show() # exibe #lab1.viewImages([original, image], ['Imagem original', 'Imagem equalizada']) #lab1.viewHistograms(image) return saveChanges(original, image)