opencv 학습 9 : 이미지 히스토그램, 히스토그램 응용 프로그램, 히스토그램 역 투영

1. 이미지 히스토그램

1.1 numpy 구현

기능 : hist (데이터 소스, 픽셀 레벨)
데이터 소스 : 이미지는 1 차원 배열이어야합니다.
픽셀 레벨 : 일반적으로 256, 즉 [0-255]
np.raval ()은 1 차원으로 다차원 배열을 실현할 수 있습니다. .

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

스크린 샷 실행 :
여기에 사진 설명 삽입

1.2 OpenCV 구현

hist = cv2.calcHist (images, channels, mask, histsize, ranges, accumulate)
hist : 히스토그램
이미지 : 원본 이미지, 형식 [src], 대괄호로 묶어야 함
채널 : 채널, 회색 직접 [0], BGR 해당 [0], [1], [2]
마스크 : 마스크 이미지. 그래프가 크면 그래프 일부의 히스토그램을 계산하고 마스크가 필요합니다.
histsize : 대괄호로 묶어야하는 BINS의 수. 일반적으로 [256]
범위 : 픽셀 값 범위, 일반적으로 [0,255]
누적 : 식별을 누적합니다. 선택적 매개 변수, 기본값은 false이며 여러 그림의 히스토그램을 계산하려면 true로 설정하십시오.

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

스크린 샷 실행 :
여기에 사진 설명 삽입
다른 사진 :
여기에 사진 설명 삽입

2. 이미지 히스토그램 애플리케이션

2.1 글로벌 히스토그램 이퀄라이제이션

히스토그램 이퀄라이제이션은 회색 그래프를 기반으로하며
원리는 위에서 언급 한 기본 링크에 나와 있습니다.
효과 : 대비 그래프가 향상되었습니다.

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

스크린 샷 실행 :
여기에 사진 설명 삽입

2.2 부분 히스토그램 평준화

로컬 적응 형 이미지 히스토그램 이퀄라이제이션
적응 형 히스토그램 이퀄라이제이션 (AHE)은 이미지의 대비를 개선하는 데 사용되는 컴퓨터 이미지 처리 기술입니다. 일반 히스토그램 등화 알고리즘과 달리 AHE 알고리즘은 이미지의 로컬 히스토그램을 계산 한 다음 밝기를 재분배하여 이미지 대비를 변경합니다. 따라서 알고리즘은 이미지의 로컬 대비를 개선하고 더 많은 이미지 세부 정보를 얻는 데 더 적합합니다.

그러나 AHE는 이미지의 동일한 영역에서 노이즈를 과도하게 증폭시키는 문제가 있습니다. 또 다른 적응 형 히스토그램 등화 알고리즘 인 CLAHE (Limited Contrast Histogram equalization) 알고리즘은 이러한 불리한 증폭을 제한 할 수 있습니다.

cv2.createCLAHE (clipLimit = 5.0, tileGridSize = (8, 8))
첫 번째 매개 변수의 의미는 clipLimit보다 큰 히스토그램의 작은 부분이 잘리고 전체 이미지에 균등하게 분산된다는 것입니다. 두 번째 매개 변수의 의미 분할 된 작은 영역의 크기입니다. clipLimit의 일반 값은 40으로 설정되어 있습니다. 사용자 정의하면 값이 클수록 균질화 효과가 더 분명해집니다. 값이 0에 가까울수록 원본 이미지와 다르지 않습니다.
회로도 :
여기에 사진 설명 삽입

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

스크린 샷 실행 :
대비 clipLimit이 1 3 5로 설정되고
여기에 사진 설명 삽입대비가 1.0 인 경우의 효과
여기에 사진 설명 삽입

2.3 히스토그램 비교

두 개의 입력 이미지에서 히스토그램 H1 및 H2를 계산하고 동일한 스케일 공간으로 정규화 한 다음 H1과 H2 사이의 거리를 계산하여 두 히스토그램의 유사성을 얻고 이미지 자체의 유사성을 비교합니다.
히스토그램 비교 기능

cv2.compareHist (H1, H2, method)
여기서 :

H1, H2는 비교할 영상의 히스토그램
방법-
비교 방법 비교 방법 (방법)

상관 관계 비교 (method = cv.HISTCMP_CORREL) 값이 클수록 상관도가 높고, 최대 값이 1, 최소값이 0 인
카이 제곱 비교 (method = cv.HISTCMP_CHISQR 값이 작을수록 상관도가 높음) , 최대 값은 상한 없음, 최소값 0
Bhattacharyya 거리 비교 (method = cv.HISTCMP_BHATTACHARYYA) 값이 작을수록 상관 관계가 높고 최대 값이 1, 최소값이 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()

여기에 사진 설명 삽입Bhattacharyya 거리가 클수록 그림 차이가 커집니다.

3. 히스토그램 백 프로젝션

히스토그램 백 프로젝션 방법은 주어진 히스토그램 정보를 통해 이미지에서 해당 픽셀 분포 영역을 찾습니다 .Opencv는 두 가지 알고리즘을 제공합니다. 하나는 픽셀 기반이고 다른 하나는 블록 기반입니다.
여기에 사진 설명 삽입
2D 히스토그램 설정
히스토그램은 2D를 기반으로하며 먼저 2D 히스토그램을 계산하여 설정합니다.

히스토그램을 계산하기 위해 cv2.calcHist () 함수를 사용하는 것은 간단하고 편리합니다. 컬러 히스토그램을 그리려면 먼저 이미지의 색 공간을 BGR에서 HSV로 변환해야합니다. (2 차원 히스토그램을 계산하려면 BGR에서 HSV로 변환해야합니다.) 2D 히스토그램을 계산하려면 함수의 매개 변수를 다음과 같이 수정해야합니다.
• channels = [0, 1] H 및 S 채널을 동시에 처리해야하기 때문입니다.
• bins = [180, 256] H 채널은 180, S 채널은 256입니다. 다른 값 (180,256 미만)을 쓰면 채널이 병합 된 것입니다.
• range = [0, 180, 0, 256] H의 값 범위는 0 ~ 180이고 S의 값 범위는 0 ~ 256입니다.
hist = cv2.calcHist ([이미지], [0, 1], 없음, [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()

스크린 샷 실행 :
여기에 사진 설명 삽입

3.2 히스토그램 역 투영

당분간은 조금 모호해 follow up

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

원래 템플릿 ROI
여기에 사진 설명 삽입는 대상 이미지에서 템플릿과 유사한 영역을 찾는 것입니다 (히스토그램이 유사 함).
결과 :
여기에 사진 설명 삽입ret, thresh = cv.threshold (dst, 200, 255, 0) 값을 수정하여 개선 .

추천

출처blog.csdn.net/weixin_44145452/article/details/112484138