opencv learning nine: histogramme d'image, application d'histogramme, rétroprojection d'histogramme

1. Histogramme d'image

1.1 implémentation numpy

Fonction: hist (source de données, niveau de pixel)
Source de données: image, doit être un tableau unidimensionnel
Niveau de pixel: généralement 256, ce qui signifie que [0-255]
np.raval () peut réaliser un tableau multidimensionnel à unidimensionnel .

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()

Exécuter la capture d'écran:
Insérez la description de l'image ici

1.2 Implémentation OpenCV

hist = cv2.calcHist (images, canaux, masque, histsize, plages, accumuler)
hist: histogramme
images: image originale, format [src], doivent être entre crochets
canaux: canal, gris direct [0], BGR correspond [0], [1], [2]
masque: image de masque. Si un graphique est volumineux, l'histogramme d'une partie du graphique doit être calculé et un masque est requis.
histsize: le nombre de BINS, qui doit être placé entre crochets. Généralement [256]
plages: plage de valeurs de pixels, généralement [0,255]
accumuler: accumuler l'identification. Paramètre facultatif, par défaut false, défini sur true pour calculer l'histogramme de plusieurs images.

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()

Exécuter la capture d'écran:
Insérez la description de l'image ici
Une autre image:
Insérez la description de l'image ici

2. Application d'histogramme d'image

2.1 Égalisation globale de l'histogramme

L'égalisation de l'histogramme est basée sur le graphique gris. Le
principe est illustré dans le lien de base mentionné ci-dessus.
Effet: le graphique de contraste est amélioré

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()

Exécuter la capture d'écran:
Insérez la description de l'image ici

2.2 Égalisation partielle de l'histogramme

Égalisation d'histogramme d'image adaptative localement
L' égalisation d'histogramme adaptative (AHE) est une technologie de traitement d'image par ordinateur utilisée pour améliorer le contraste d'une image. Différent de l'algorithme d'égalisation d'histogramme ordinaire, l'algorithme AHE modifie le contraste de l'image en calculant l'histogramme local de l'image, puis en redistribuant la luminosité. Par conséquent, l'algorithme est plus adapté pour améliorer le contraste local de l'image et obtenir plus de détails sur l'image.

Cependant, AHE a le problème d'amplifier excessivement le bruit dans la même zone de l'image Un autre algorithme d'égalisation adaptative d'histogramme, l'algorithme d'égalisation d'histogramme à contraste limité (CLAHE), peut limiter cette amplification défavorable.

cv2.createCLAHE (clipLimit = 5.0, tileGridSize = (8, 8))
La signification du premier paramètre est que la petite partie de l'histogramme plus grande que clipLimit sera coupée et uniformément répartie sur toute l'image; la signification du deuxième paramètre Est la taille de la petite zone divisée. La valeur générale de clipLimit est définie sur 40. S'il est personnalisé, plus la valeur est élevée, plus l'effet d'homogénéisation est évident. Plus la valeur est proche de zéro, elle n'est pas différente de l'image d'origine. Le
diagramme schématique:
Insérez la description de l'image ici

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()

Exécuter la capture d'écran: l'effet lorsque le
contraste clipLimit est défini sur 1 3 5 et le
Insérez la description de l'image icicontraste est de 1,0
Insérez la description de l'image ici

2.3 Comparaison des histogrammes

Calculez les histogrammes H1 et H2 à partir des deux images d'entrée, normalisez-les au même espace d'échelle, puis calculez la distance entre H1 et H2 pour obtenir la similitude des deux histogrammes et comparer la similitude des images elles-mêmes.
Fonction de comparaison d'histogramme

cv2.compareHist (H1, H2, méthode)
où:

H1, H2 sont les
méthodes d' histogramme des images à comparer - méthode de
comparaison de méthode de comparaison (méthode)

La valeur de la comparaison de corrélation (méthode = cv.HISTCMP_CORREL) est plus grande, le degré de corrélation est plus élevé, la valeur maximale est 1, la valeur minimale est 0
Comparaison chi carré (méthode = cv.HISTCMP_CHISQR la valeur est plus petite, le degré de corrélation est plus élevé , la valeur maximale n'est pas de limite supérieure, valeur minimale 0
Comparaison de distance Bhattacharyya (méthode = cv.HISTCMP_BHATTACHARYYA) Plus la valeur est petite, plus la corrélation est élevée, la valeur maximale est 1, la valeur minimale est 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()

Insérez la description de l'image iciPlus la distance Bhattacharyya est grande, plus la différence d'image est grande

3. Rétroprojection d'histogramme

La méthode de rétroprojection d'histogramme trouve la zone de distribution de pixels correspondante dans l'image à travers les informations d'histogramme données. Opencv fournit deux algorithmes, l'un est basé sur des pixels et l'autre est basé sur des blocs.
Insérez la description de l'image ici
Établissement de l'histogramme 2D L'
histogramme est basé sur 2D, calculez d'abord l'histogramme 2D à établir.

Il est simple et pratique d'utiliser la fonction cv2.calcHist () pour calculer l'histogramme. Si vous souhaitez dessiner un histogramme de couleurs, vous devez d'abord convertir l'espace colorimétrique de l'image de BGR en HSV. (N'oubliez pas que pour calculer un histogramme à deux dimensions, vous devez convertir de BGR en HSV). Pour calculer l'histogramme 2D, les paramètres de la fonction doivent être modifiés comme suit:
• channels = [0, 1] Parce que nous devons traiter les canaux H et S en même temps.
• bins = [180, 256] Le canal H est 180, le canal S est 256. Si vous écrivez d'autres valeurs (inférieures à 180 256), cela signifie que le canal est fusionné.
• range = [0, 180, 0, 256] La plage de valeurs de H est de 0 à 180 et la plage de valeurs de S est de 0 à 256.
hist = cv2.calcHist ([image], [0, 1], Aucun, [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()

Exécuter la capture d'écran:
Insérez la description de l'image ici

3.2 Rétroprojection d'histogramme

C'est un peu vague pour le moment, suivez

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()

Le retour sur investissement du modèle d'origine
Insérez la description de l'image iciest de trouver une zone similaire au modèle de l'image cible (l'histogramme est similaire). Le
résultat:
Insérez la description de l'image icimodifiez la valeur de ret, thresh = cv.threshold (dst, 200, 255, 0) pour être meilleur .

Je suppose que tu aimes

Origine blog.csdn.net/weixin_44145452/article/details/112484138
conseillé
Classement