207 lines
6.7 KiB
Python
207 lines
6.7 KiB
Python
#coding:utf-8
|
|
|
|
import cv2
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
|
|
#绘制灰度直方图
|
|
def gray_histogram(img,bins=256):
|
|
img=np.uint8(img)
|
|
# img1=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#opencv默认的imread是以BGR的方式进行存储的
|
|
histr = cv2.calcHist([img],[0],None,[bins],[0,255])#绘制直方图
|
|
# plt.bar(np.arange(bins),histr.flatten())
|
|
return histr
|
|
|
|
|
|
#绘制彩色直方图
|
|
def colorHistogram(imgName):
|
|
color = ('b', 'g', 'r')
|
|
#绘制灰度图像的直方图
|
|
img1=cv2.imread(imgName)
|
|
img2=cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)#opencv默认的imread是以BGR的方式进行存储的
|
|
# 而matplotlib的imshow默认则是以RGB格式展示所以此处我们必须对图片的通道进行转换
|
|
plt.subplot(221)
|
|
plt.title('color image'), plt.xticks([]), plt.yticks([])
|
|
plt.imshow(img2)
|
|
plt.subplot(222)
|
|
plt.title('colorHistogram image')
|
|
for i, col in enumerate(color):
|
|
histr = cv2.calcHist([img2], [i], None, [256], [0, 256])
|
|
plt.plot(histr, color=col)
|
|
plt.savefig("pic_change.jpg")
|
|
|
|
#掩膜直方图
|
|
def mask_histogram(img,imgMask,binSize):
|
|
hight,weight = img.shape
|
|
mask0 = cv2.resize(imgMask,(weight,hight))
|
|
_ , mask= cv2.threshold(mask0, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
|
masked_img = cv2.bitwise_and(img, img, mask=mask) # 掩模的黑色区域(像素值为0)用来遮盖原图img,cv2.bitwise_and()函数的功能是位与
|
|
cv2.imwrite('mask.jpg',masked_img)
|
|
histr = cv2.calcHist([img], [0], mask, [256], [0, 256])
|
|
plt.plot(histr)
|
|
return histr, masked_img
|
|
#
|
|
# #局部图像直方图
|
|
# def locality_histogram (imgName,x=0,y=0,w=0.5,h=0.6):
|
|
# imgNewName = 'huan.png'
|
|
# img = Image.open(imgName)
|
|
# img_size = img.size
|
|
# weight,hight = img_size
|
|
# x = x * weight
|
|
# y = y * hight
|
|
# w = w * weight
|
|
# h = h * hight
|
|
# region = img.crop((x, y, x + w, y + h))
|
|
# region.save(imgNewName)
|
|
# img1=cv2.imread(imgNewName)
|
|
# histr = cv2.calcHist([img1], [0], None, [256], [0, 256])#绘制直方图
|
|
# return histr, region
|
|
|
|
#直方图均衡化
|
|
def equalization_histogram(img):
|
|
equ = cv2.equalizeHist(img) #对图像进行直方图均衡化处理
|
|
histogram = cv2.calcHist([equ], [0], None, [256], [0, 256])#分组越多得到的均衡化直方图效果越明显
|
|
return histogram, equ
|
|
|
|
#规定化直方图
|
|
# type=1目标直方图是正三角形, type=2倒三角形, type=3平形,
|
|
def regulation_histogram(img,type=1,mapSML=True):
|
|
'''
|
|
:param img:
|
|
:param type: type=1目标直方图是正三角形, type=2倒三角形, type=3平形,
|
|
:param mapSML: True是SML False是GML
|
|
:return: 直方图和图像
|
|
'''
|
|
rows,cols = img.shape
|
|
gray_flat = img.reshape((rows*cols,))
|
|
|
|
dif = np.zeros((256,256),np.float) #用于存放原直方图与目标直方图的差
|
|
S = np.zeros((rows,cols),np.uint8) #单映射规定化后图像
|
|
G = np.zeros((rows,cols),np.uint8) #组映射规定化后图像
|
|
src = np.zeros((256,),np.int32) #原直方图
|
|
dst = np.zeros((256,),np.int32) #规定直方图
|
|
H_SML = np.zeros((256,),np.int32) #单映射的映射关系
|
|
H_GML = np.zeros((256,), np.int32) #组映射的映射关系
|
|
SH = np.zeros((256,),np.float) #单映射规定化后直方图
|
|
GH = np.zeros((256,),np.float) #组映射规定化后直方图
|
|
|
|
# 计算原图像各个灰度级数量
|
|
for index,value in enumerate(gray_flat):
|
|
src[value] += 1
|
|
|
|
#归一化处理
|
|
src_pro = src/sum(src)
|
|
|
|
# 计算灰度级的累计分布
|
|
for i in range(1,256):
|
|
src_pro[i] = src_pro[i - 1] + src_pro[i]
|
|
|
|
#目标直方图为正直角三角形
|
|
if type==1:
|
|
for i in range(256):
|
|
dst[i] = i
|
|
#目标直方图为倒三角形
|
|
if type==2:
|
|
for i in range(256):
|
|
dst[i] = 256-i
|
|
#目标直方图是平行的
|
|
if type==3:
|
|
for i in range(256):
|
|
dst[i] = 128
|
|
|
|
# plt.plot(dst)
|
|
# plt.show()
|
|
#归一化处理
|
|
dst_pro=dst/sum(dst)
|
|
|
|
# 计算规定化灰度级的累计分布
|
|
for i in range(1,256):
|
|
dst_pro[i] = dst_pro[i - 1] + dst_pro[i]
|
|
|
|
#|V2-V1|计算目标直方图与原直方图的差
|
|
for i in range(256):
|
|
for j in range(256):
|
|
dif[i,j] = abs(src_pro[i]-dst_pro[j])
|
|
|
|
#SML单映射
|
|
if mapSML==True:
|
|
for i in range(256):
|
|
minx = 0
|
|
minvalue = dif[i,0]
|
|
for j in range(1,256):
|
|
if(dif[i,j]<minvalue):
|
|
minvalue=dif[i,j]
|
|
minx=j
|
|
H_SML[i]=minx #将灰度i映射为灰度minx
|
|
|
|
for i in range(256):
|
|
SH[H_SML[i]]+= src[i] #src[i]是灰度为i的像素个数,SH是规定化后的直方图
|
|
|
|
SHpro = SH/sum(SH)
|
|
|
|
for i in range(rows):
|
|
for j in range(cols):
|
|
S[i,j]=H_SML[img[i,j]] #S是单映射得到的图像,将灰度值img[i,j]映射为H_SML[img[i,j]]
|
|
return SHpro, S
|
|
else:
|
|
#GML群映射
|
|
lastStartY = 0
|
|
lastEndY = 0
|
|
startY = 0
|
|
endY = 0
|
|
for i in range(256):
|
|
minvalue = dif[0,i]
|
|
for j in range(1,256):
|
|
if(minvalue>dif[j,i]):
|
|
minvalue=dif[j,i]
|
|
endY=j
|
|
if(startY != lastStartY ) or (endY != lastEndY):
|
|
for k in range(startY,endY+1):
|
|
H_GML[k]=i
|
|
|
|
lastStartY=startY
|
|
lastEndY=endY
|
|
startY=lastEndY+1
|
|
|
|
for i in range(256):
|
|
GH[H_GML[i]]+= src[i] #组映射直方图
|
|
|
|
for i in range(rows):
|
|
for j in range(cols):
|
|
G[i,j]=H_GML[img[i,j]] #G是组映射得到的图像
|
|
|
|
GHpro = GH/sum(GH)
|
|
return GHpro, G
|
|
|
|
# plt.subplot(231)
|
|
# # plt.hist(img.ravel(), 256, [0, 256]) # 绘制直方图,img.ravel()将图像转为一维数组
|
|
# plt.plot(src)
|
|
# plt.title('original image')
|
|
# plt.subplot(232)
|
|
# plt.title('SML单映射直方图')
|
|
# plt.plot(SH)
|
|
# plt.subplot(233)
|
|
# plt.title('GML组映射直方图')
|
|
# plt.plot(GH)
|
|
# plt.subplot(234)
|
|
# plt.title('original image'),plt.xticks([]), plt.yticks([])
|
|
# plt.imshow(img)
|
|
# plt.subplot(235)
|
|
# plt.title('SML image'), plt.xticks([]), plt.yticks([])
|
|
# plt.imshow(S)
|
|
# plt.subplot(236)
|
|
# plt.title('GML image'), plt.xticks([]), plt.yticks([])
|
|
# plt.imshow(G)
|
|
|
|
|
|
|
|
if __name__=="__main__":
|
|
img=cv2.imread(r'.\img\6.png',0)
|
|
# imgMask=cv2.imread(r'.\img\mask.jpg',0)
|
|
# mask_histogram(img,imgMask,64)
|
|
#colorHistogram('timg.jpg')
|
|
#maskHistogram('timg.jpg')
|
|
#equalizationHistogram('timg.jpg')
|
|
#localityHistogram('timg.jpg')
|
|
regulation_histogram(img)
|
|
plt.show() |