opencv learning nine: histograma de imagem, aplicação de histograma, retroprojeção do histograma

1. Histograma de imagem

1.1 implementação numpy

Função: hist (fonte de dados, nível de pixel)
Fonte de dados: imagem, deve ser uma matriz unidimensional
Nível de pixel: geralmente 256, o que significa [0-255]
np.raval () pode realizar uma matriz multidimensional para unidimensional .

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

def plot_demo(image):
    plt.hist(image.ravel(),256,[0,256])# image.ravel()将图像展开,256为bins数量,[0, 256]为范围
    # plt.hist(image.ravel(),256)#两种写法都对
    plt.show()
    
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
plot_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

Execute a captura de tela:
Insira a descrição da imagem aqui

1.2 Implementação do OpenCV

hist = cv2.calcHist (imagens, canais, máscara, tamanho de hist, intervalos, acumular)
hist:
imagens de histograma : imagem original, formato [src], precisa ser colocado entre colchetes
canais: canal, cinza direto [0], BGR corresponde [0], [1], [2]
máscara: máscara de imagem. Se um gráfico for grande, o histograma de parte do gráfico precisa ser calculado e uma máscara é necessária.
histsize: o número de BINS, que deve ser colocado entre colchetes. Geralmente [256]
faixas: faixa de valor de pixel, geralmente [0,255]
acumular: acumular identificação. Parâmetro opcional, padrão falso, definido como verdadeiro para calcular o histograma de várias imagens.

def image_hist(image):
    color = ('blue', 'green', 'red')
    for i, color in enumerate(color):
 
        # 计算出直方图,calcHist(images, channels, mask, histSize(有多少个bin), ranges[, hist[, accumulate]]) -> hist
        # hist 是一个 256x1 的数组,每一个值代表了与该灰度值对应的像素点数目。
 
        hist = cv.calcHist(image, [i], None, [256], [0, 256])
        print(hist.shape)
        plt.plot(hist, color=color)
        plt.xlim([0, 256])
    plt.show()

Executar captura de tela:
Insira a descrição da imagem aqui
Outra imagem:
Insira a descrição da imagem aqui

2. Aplicação de histograma de imagem

2.1 Equalização do histograma global

A equalização do histograma é baseada no gráfico cinza. O
princípio é mostrado no link básico mencionado acima.
Efeito: o gráfico de contraste é aprimorado

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

def equalHist_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    dst = cv.equalizeHist(gray)
    cv.imshow("equalHist_demo", dst)

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)

equalHist_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

Execute a captura de tela:
Insira a descrição da imagem aqui

2.2 Equalização parcial do histograma

Equalização de histograma de imagem adaptável localmente A equalização de histograma
adaptativa (AHE) é uma tecnologia de processamento de imagem de computador usada para melhorar o contraste de uma imagem. Diferente do algoritmo de equalização de histograma comum, o algoritmo AHE altera o contraste da imagem calculando o histograma local da imagem e redistribuindo o brilho. Portanto, o algoritmo é mais adequado para melhorar o contraste local da imagem e obter mais detalhes da imagem.

No entanto, o AHE tem o problema de amplificar excessivamente o ruído na mesma área da imagem. Outro algoritmo de equalização de histograma adaptativo, o algoritmo de equalização de histograma de contraste limitado (CLAHE), pode limitar essa amplificação desfavorável.

cv2.createCLAHE (clipLimit = 5.0, tileGridSize = (8, 8))
O significado do primeiro parâmetro é que a pequena parte do histograma maior que clipLimit será recortada e distribuída uniformemente por toda a imagem; o significado do segundo parâmetro É o tamanho da pequena área dividida. O valor geral de clipLimit é definido como 40. Se for personalizado, quanto maior for o valor, mais óbvio será o efeito da homogeneização. Quanto mais próximo o valor estiver de zero, não é diferente da imagem original. O
diagrama esquemático:
Insira a descrição da imagem aqui

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#局部均衡化
def clahe_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    clahe = cv.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8)) #1.0 3.0 5.0对比度会增加
    dst = clahe.apply(gray)
    cv.imshow("clahe_demo", dst)

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)

clahe_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

Executar captura de tela: o efeito quando o
contraste clipLimit é definido como 1 3 5 e o
Insira a descrição da imagem aquicontraste é 1.0
Insira a descrição da imagem aqui

2.3 Comparação de histogramas

Calcule os histogramas H1 e H2 das duas imagens de entrada, normalize-os para o mesmo espaço de escala e, em seguida, calcule a distância entre H1 e H2 para obter a similaridade dos dois histogramas e comparar a similaridade das próprias imagens.
Função de comparação de histograma

cv2.compareHist (H1, H2, método)
onde:

H1, H2 são os
métodos de histograma das imagens a serem comparadas - método de
comparação de método de comparação (método)

O valor de comparação de correlação (método = cv.HISTCMP_CORREL) é maior, o grau de correlação é maior, o valor máximo é 1, o valor mínimo é 0
Comparação de qui-quadrado (método = valor cv.HISTCMP_CHISQR é menor, o grau de correlação é maior , o valor máximo não tem Limite superior, valor mínimo 0
Comparação de distância Bhattacharyya (método = cv.HISTCMP_BHATTACHARYYA) Quanto menor o valor, maior a correlação, o valor máximo é 1, o valor mínimo é 0

import cv2 as cv
import numpy as np


#rgb直方图
def create_rgb_hist(image):
    h, w, c = image.shape
    rgbHist = np.zeros([16*16*16, 1], np.float32)#直方图初始化
    bsize = 256 / 16
    for row in range(h):
        for col in range(w):
            b = image[row, col, 0]
            g = image[row, col, 1]
            r = image[row, col, 2]
            index = np.int(b/bsize)*16*16 + np.int(g/bsize)*16 + np.int(r/bsize)
            rgbHist[np.int(index), 0] = rgbHist[np.int(index), 0] + 1#出现了就加1
    return rgbHist
 #比较函数
def hist_compare(image1, image2):
    hist1 = create_rgb_hist(image1)
    hist2 = create_rgb_hist(image2)
    match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)#比较方法1,越小越相似
    match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)#相关性越大越相似
    match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)#卡方越大约不相似
    print("巴氏距离: %s, 相关性: %s, 卡方: %s"%(match1, match2, match3))

print("--------- Hello Python ---------")
src1 = cv.imread("renwu1.jpg")
src2 = cv.imread("renwu.jpg")
src1=cv.resize(src1,None,fx=0.5,fy=0.5)
src2=cv.resize(src2,None,fx=0.5,fy=0.5)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src1)
cv.imshow("image2", src2)
hist_compare(src1, src2)
cv.waitKey(0)
cv.destroyAllWindows()


image1 = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")
image2 = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/quzao.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("image1", image1)
cv.imshow("image2", image2)
hist_compare(image1, image2)
cv.waitKey(0)
cv.destroyAllWindows()

Insira a descrição da imagem aquiQuanto maior for a distância Bhattacharyya, maior será a diferença de imagem

3. Retroprojeção do histograma

O método de retroprojeção do histograma encontra a área de distribuição de pixels correspondente na imagem por meio das informações de histograma fornecidas.O Opencv fornece dois algoritmos, um baseado em pixels e o outro em blocos.
Insira a descrição da imagem aqui
Estabelecimento do histograma 2D O
histograma é baseado no 2D, primeiro calcule o histograma 2D para estabelecer.

É simples e conveniente usar a função cv2.calcHist () para calcular o histograma. Se você deseja desenhar um histograma de cores, primeiro precisa converter o espaço de cores da imagem de BGR para HSV. (Lembre-se, para calcular um histograma bidimensional, você precisa converter de BGR para HSV). Para calcular o histograma 2D, os parâmetros da função precisam ser modificados da seguinte forma:
• canais = [0, 1] Porque precisamos processar os canais H e S ao mesmo tempo.
• bins = [180, 256] canal H é 180, canal S é 256. Se você escrever outros valores (menos de 180.256), significa que o canal foi mesclado.
• intervalo = [0, 180, 0, 256] O intervalo de valores de H é de 0 a 180 e o intervalo de valores de S é de 0 a 256.
hist = cv2.calcHist ([imagem], [0, 1], Nenhum, [32, 32], [0, 180, 0, 256])

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#直方图的建立
def hist2d_demo(image):
    hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
    hist = cv.calcHist([image], [0, 1], None, [180, 256], [0, 180, 0, 256])
    #cv.imshow("hist2d", hist)
    plt.imshow(hist, interpolation='nearest')#nearest邻近点插值
    plt.title("2D Histogram")
    plt.show()

src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")  #读取图片位置
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hist2d_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

Execute a captura de tela:
Insira a descrição da imagem aqui

3.2 Retroprojeção do histograma

É um pouco vago por enquanto, acompanhamento

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


def back_projection_demo():
    # ROI区域
    roi= cv.imread("head.png")
    #roi=cv.resize(roi,None,fx=0.5,fy=0.5)
    #目标搜索区域
    target = cv.imread("renwu.jpg")
    target= cv.resize(target, None, fx=0.2, fy=0.2)
    roi_hsv = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
    target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV)

    # show images
    cv.imshow("roi", roi)
    #cv.imshow("target", target)

    roiHist = cv.calcHist([roi_hsv], [0, 1], None, [180,256], [0, 180, 0, 256])#2D直方图
    cv.normalize(roiHist, roiHist, 0, 255, cv.NORM_MINMAX)#归一化到0-255
    dst = cv.calcBackProject([target_hsv], [0, 1], roiHist, [0, 180, 0, 256], 1)
    #cv.imshow("backProjectionDemo", dst)

    # 此处卷积可以把分散的点连在一起
    disc = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
    dst = cv.filter2D(dst, -1, disc)
    # threshold and binary AND
    ret, thresh = cv.threshold(dst, 200, 255, 0)
    # 别忘了是三通道图像,因此这里使用 merge 变成 3 通道
    thresh = cv.merge((thresh, thresh, thresh))
    # 按位操作
    res = cv.bitwise_and(target, thresh)
    res = np.hstack((target, thresh, res))
    cv.imshow('res',res)
    #cv.imwrite('res.jpg', res)

back_projection_demo()
cv.waitKey(0)

cv.destroyAllWindows()

O modelo original de ROI
Insira a descrição da imagem aquié encontrar uma área semelhante ao modelo da imagem alvo (o histograma é semelhante). O
resultado:
Insira a descrição da imagem aquimodifique o valor de ret, thresh = cv.threshold (dst, 200, 255, 0) para melhorar .

Acho que você gosta

Origin blog.csdn.net/weixin_44145452/article/details/112484138
Recomendado
Clasificación