Advertisement

OpenCV图像处理技术之图像直方图

阅读量:

©Fu Xianjun. All Rights Reserved.所有素材来自于小傅老师。

我们公布上一期的任务答案吧!

开始今天的学习了,搬好小板凳!

重点:直方图的绘制方法,直方图的均衡

难点:直方图的比较,直方图阈值法

图像直方图是图像内灰度值的统计特性与图像灰度值之间的函数,直方图统计图像内各个灰度级出现的次数。

直方图是数值数据分布的精确图形表示。 这是一个连续变量(定量变量)的概率分布的估计,并且被卡尔·皮尔逊(Karl Pearson)首先引入。它是一种条形图。 构建直方图: ①将值的范围分段 ②计算每个间隔中有多少值

作用:

(1)显示图像质量波动的状态 (2)较直观地传递有关过程图像质量状况的信息 (3)掌握过程的状况,从而确定在什么地方集中力量进行图像质量改进工作。

回忆直方图表现的摄影状态,欠曝过曝

使用plt.hist绘制直方图,并修改分割参数,256,122,50并显示

import cv2
import matplotlib.pyplot as plt
img1=cv2.imread("hj.jpg",0)
cv2.imshow("img1",img1)
plt.hist(img1.ravel(),256,facecolor='yellowgreen')
cv2.waitKey()
cv2.destroyAllWindows()

import cv2
import matplotlib.pyplot as plt
img1=cv2.imread("bd.jpg")
cv2.imshow("img1",img1)
plt.hist(img1.ravel(),256)
cv2.waitKey()
cv2.destroyAllWindows()

cv2.calcHist(images,channels,mask,histSize,ranges,accumulate)

channels:指定通道编号。通道编号需要用“[]”括起来。 mask:掩模图像。当统计整幅图像的直方图时,将这个值设为None histSize: BINS的值,该值需要用“[]”括起来。 ranges:即像素值范围。例如,8位灰度图像的像素值范围是[0,255] accumulate:累计(累积、叠加)标识,默认值为False

使用cv2.calcHist绘制直方图,并修改分割参数,256,122,50并显示

import cv2
import numpy as np
img=cv2.imread("bd.jpg")
hist = cv2.calcHist([img],[0],None,[256],[0,255])plt.plot(hist,color='b')

练习1:绘制彩色的直方图

import cv2
import numpy as np
img=cv2.imread("bd.jpg")
histb = cv2.calcHist([img],[0],None,[256],[0,255])
histg = cv2.calcHist([img],[1],None,[256],[0,255])
histr = cv2.calcHist([img],[2],None,[256],[0,255])
plt.plot(histb,color='b')
plt.plot(histg,color='g')
plt.plot(histr,color='r')

练习1.1 彩色直方图封装

import cv2
import numpy as np
from matplotlib import pyplot as plt
def image_hist(image):
color = ('blue', 'green', 'red')
for i, color in enumerate(color):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.show()
img=cv2.imread("bd.jpg")
image_hist(img)

练习2:使用掩膜进行直方图绘制

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread("hj.jpg",0)
w,h=img.shape
mask=np.zeros([w,h],np.uint8)
mask[(w-200):w,0:200]=255
hist = cv2.calcHist([img],[0],None,[256],[0,255])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,255])

cv2.imshow('mask',mask)

plt.plot(hist,color='b')
plt.plot(hist_mask,color='g')
cv2.waitKey()
cv2.destroyAllWindows()

直方图均衡化

import cv2
import numpy as np
img=cv2.imread("hj.jpg",0)
equ=cv2.equalizeHist(b)
hist = cv2.calcHist([equ],[0],None,[256],[0,255])
plt.plot(hist,color='b')
cv2.imshow("equ",equ)
cv2.waitKey()
cv2.destroyAllWindows()

练习3:彩色图像直方图均衡化

import cv2
import numpy as np
img=cv2.imread("qb.jpg")
b,g,r=cv2.split(img)
equb=cv2.equalizeHist(b)
equg=cv2.equalizeHist(g)
equr=cv2.equalizeHist(r)
img_new=cv2.merge([equb,equg,equr])
histb = cv2.calcHist([img_new],[0],None,[256],[0,255])
histg = cv2.calcHist([img_new],[1],None,[256],[0,255])
histr = cv2.calcHist([img_new],[2],None,[256],[0,255])
plt.plot(histb,color='b')
plt.plot(histg,color='g')
plt.plot(histr,color='r')
cv2.imshow("img",img)
cv2.imshow("img_new",img_new)
cv2.waitKey()
cv2.destroyAllWindows()

练习4:彩色图像直方图自适应均衡化

import cv2
import numpy as np
img=cv2.imread("qb.jpg")
b,g,r=cv2.split(img)
clah=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
equb=clah.apply(b)
equg=clah.apply(g)
equr=clah.apply(r)
img_new=cv2.merge([equb,equg,equr])
histb = cv2.calcHist([img_new],[0],None,[256],[0,255])
histg = cv2.calcHist([img_new],[1],None,[256],[0,255])
histr = cv2.calcHist([img_new],[2],None,[256],[0,255])
plt.plot(histb,color='b')
plt.plot(histg,color='g')
plt.plot(histr,color='r')
cv2.imshow("img",img)
cv2.imshow("img_new",img_new)
cv2.waitKey()
cv2.destroyAllWindows()

直方图比较

import cv2
import numpy as np
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 = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
rgbhist[int(index), 0] += 1
return rgbhist

def hist_compare(image1, image2):
hist1 = create_rgb_hist(image1)
hist2 = create_rgb_hist(image2)
match1 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_BHATTACHARYYA)
match2 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
match3 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CHISQR)
print("巴氏距离:%s, 相关性:%s, 卡方:%s" %(match1, match2, match3))

img1 = cv2.imread("dog1.jpg")
cv2.imshow("dog1", img1)
img2 = cv2.imread("dog3.jpg")
cv2.imshow("dog3", img2)
hist_compare(img1, img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

直方图阈值法

import cv2
import numpy as np

#计算灰度直方图
def calcGrayHist(grayimage):
#灰度图像矩阵的高,宽
rows, cols = grayimage.shape
print(grayimage.shape)
#存储灰度直方图
grayHist = np.zeros([256],np.uint64)
for r in range(rows):
for c in range(cols):
grayHist[grayimage[r][c]] += 1
return grayHist

#阈值分割:直方图阈值法
def threshTwoPeaks(image):
if len(image.shape) == 2:
gray = image
else:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(666666)
#计算灰度直方图
histogram = calcGrayHist(gray)
#寻找灰度直方图的最大峰值对应的灰度值
maxLoc = np.where(histogram==np.max(histogram))
firstPeak = maxLoc[0][0]
#寻找灰度直方图的第二个峰值对应的灰度值
measureDists = np.zeros([256],np.float32)
for k in range(256):
measureDists[k] = pow(k-firstPeak,2)*histogram[k]
maxLoc2 = np.where(measureDists==np.max(measureDists))
secondPeak = maxLoc2[0][0]

#找到两个峰值之间的最小值对应的灰度值,作为阈值
thresh = 0
if firstPeak > secondPeak:#第一个峰值再第二个峰值的右侧
temp = histogram[int(secondPeak):int(firstPeak)]
minloc = np.where(temp == np.min(temp))
thresh = secondPeak + minloc[0][0] + 1
else:#第一个峰值再第二个峰值的左侧
temp = histogram[int(firstPeak):int(secondPeak)]
minloc = np.where(temp == np.min(temp))
thresh =firstPeak + minloc[0][0] + 1

#找到阈值之后进行阈值处理,得到二值图
threshImage_out = gray.copy()
#大于阈值的都设置为255
threshImage_out[threshImage_out > thresh] = 255
threshImage_out[threshImage_out <= thresh] = 0
return thresh, threshImage_out

if name == "main":
img = cv2.imread('dog2.png')
thresh,threshImage_out = threshTwoPeaks(img)
print(thresh)
cv2.imshow('threshImage_out',threshImage_out)
cv2.waitKey(0)
cv2.destroyAllWindows()

今天的学习就到这里了,你学废了吗?

我们下期再见!

全部评论 (0)

还没有任何评论哟~