Opencv对比度增强 python API
直方图
%matplotlib inline
import numpy as np
import cv2
import matplotlib.pyplot as plt
def calcGrayHist(image):
#灰度图像矩阵的高和宽
rows,cols = image.shape
#存储灰度直方图
grayHist = np.zeros([256],np.uint64)
for r in range(rows):
for c in range(cols):
grayHist[image[r][c]]+=1
return grayHist
if __name__ == "__main__":
image = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
#计算灰度直方图
grayHist = calcGrayHist(image)
cv2.imshow("src",image)
cv2.waitKey(0)
#画出灰度直方图
x_range = range(256)
plt.plot(x_range,grayHist,'r',linewidth = 2, c = 'black')
#设置坐标轴范围
y_maxValue = np.max(grayHist)
plt.axis([0,255,0,y_maxValue])
#设置坐标轴标签
plt.xlabel('gray Level')
plt.ylabel('number of pixels')
#显示灰度直方图
plt.show()
%matplotlib inline
import numpy as np
import cv2
import matplotlib.pyplot as plt
if __name__ == "__main__":
image = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
#得到了图像矩阵的高和宽
rows,cols = image.shape
#将二维图像矩阵变为一维数组,便于计算灰度直方图
pixelSequence = image.reshape([rows * cols,])
#组数
numberBins = 256
#计算灰度直方图
histogram, bins, patch = plt.hist(pixelSequence,numberBins,facecolor = 'black', histtype = 'bar')
#设置坐标轴的标签
plt.xlabel(u"gray Level")
plt.ylabel(u"number of pixels")
#设置坐标轴的范围
y_maxValue = np.max(histogram)
plt.axis([0,255,0,y_maxValue])
plt.show()
线性变换
import numpy as np
I = np.array([[0,200],[23,4]],np.uint8)
O = 2*I
print(O)
O = 2.0*I#常数数据影响输出类型
print(O)
[[ 0 144]
[ 46 8]]
[[ 0. 400.]
[ 46. 8.]]
%matplotlib inline
import numpy as np
import cv2
import matplotlib.pyplot as plt
def plotHist(image):
#得到了图像矩阵的高和宽
rows,cols = image.shape
#将二维图像矩阵变为一维数组,便于计算灰度直方图
pixelSequence = image.reshape([rows * cols,])
#组数
numberBins = 256
#计算灰度直方图
histogram, bins, patch = plt.hist(pixelSequence,numberBins,facecolor = 'black', histtype = 'bar')
#设置坐标轴的标签
plt.xlabel(u"gray Level")
plt.ylabel(u"number of pixels")
#设置坐标轴的范围
y_maxValue = np.max(histogram)
plt.axis([0,255,0,y_maxValue])
plt.show()
#主函数
if __name__ == "__main__":
I = cv2.imread("c:/users/76973/desktop/picture/output_image1.jpg",cv2.IMREAD_GRAYSCALE)
#线性变换
a = 2
O = float(a)*I
# O = I.dot(float(a))
#进行数据截断,大于255的值截断为255
O[O > 255] = 255
#数据类型转换
O = np.round(O)
O = O.astype(np.uint8)
plotHist(I)
plotHist(O)
#显示原图和线性变换的结果
cv2.imshow("I",I)
cv2.imshow("O",O)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
import cv2
import matplotlib.pyplot as plt
def plotHist(image):
#得到了图像矩阵的高和宽
rows,cols = image.shape
#将二维图像矩阵变为一维数组,便于计算灰度直方图
pixelSequence = image.reshape([rows * cols,])
#组数
numberBins = 256
#计算灰度直方图
histogram, bins, patch = plt.hist(pixelSequence,numberBins,facecolor = 'black', histtype = 'bar')
#设置坐标轴的标签
plt.xlabel(u"gray Level")
plt.ylabel(u"number of pixels")
#设置坐标轴的范围
y_maxValue = np.max(histogram)
plt.axis([0,255,0,y_maxValue])
plt.show()
#主函数
if __name__ == "__main__":
I = cv2.imread("c:/users/76973/desktop/picture/output_image4.jpg",cv2.IMREAD_GRAYSCALE)
#线性变换
#得到了图像矩阵的高和宽
rows,cols = I.shape
#print(rows, cols)
a = 2
O = np.zeros((rows,cols),np.uint8)
for r in range(rows):
for c in range(cols):
if I[r,c] <170 and I[r,c]>100:
# print(I[r,c])
if 2.0*I[r,c]>255.0:
O[r,c] = 255
else:
O[r,c] = 2.0 * I[r,c]
else:
if 1.0*I[r,c]>255.0:
O[r,c] = 255
else:
O[r,c] = 1.0*I[r,c]
#进行数据截断,大于255的值截断为255
# O[O > 255] = 255
#数据类型转换
# O = np.round(O)
O = O.astype(np.uint8)
plotHist(I)
plotHist(O)
#显示原图和线性变换的结果
cv2.imshow("I",I)
cv2.imshow("O",O)
cv2.waitKey(0)
cv2.destroyAllWindows()
在这里插入图片描述
直方图正规化
import cv2
import numpy as np
import sys
#主函数
if __name__ == "__main__":
I = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
# 求 I 的最大值、最小值
Imax = np.max(I)
Imin = np.min(I)
# 要输出的最小灰度级和最大灰度级
Omin,Omax = 0, 255
#计算a 和 b 的值
a = float(Omax - Omin)/(Imax-Imin)
print(a)
b = Omin - a*Imin
print(b)
#矩阵的线性变换
O = a * I + b
#数据类型转换
O = O.astype(np.uint8)
#显示原图和直方图正规化的效果
cv2.imshow("I",I)
cv2.imshow("O",O)
cv2.waitKey(0)
cv2.destroyAllWindows()
1.0
0.0
使用normalize 函数
import cv2
src = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
#直方图正规化
dst = src.copy()
cv2.normalize(src,dst,255,0,cv2.NORM_MINMAX,cv2.CV_8U)
#显示原图与正规化效果
cv2.imshow("src",src)
cv2.imshow("dst",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
伽马变换
import cv2
import numpy as np
# 主函数
if __name__ == "__main__":
I = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
#图像归一化
fI = I/255.0
#伽马变换
gamma = 0.5
O = np.power(fI,gamma)
#显示原图和伽马变换后的效果
cv2.imshow("I",I)
cv2.imshow("O",O)
cv2.waitKey(0)
cv2.destroyAllWindows()
全局直方图均衡化
import cv2
import numpy as np
import math
def calcGrayHist(image):
#灰度图像矩阵的高和宽
rows,cols = image.shape
#存储灰度直方图
grayHist = np.zeros([256],np.uint64)
for r in range(rows):
for c in range(cols):
grayHist[image[r][c]]+=1
return grayHist
def equalHist(image):
# 灰度图像矩阵的高、宽
rows, cols = image.shape
# 第一步:计算灰度直方图
grayHist = calcGrayHist(image)
# 第二步:计算累加灰度直方图
zeroCumuMoment = np.zeros([256],np.uint32)
for p in range(256):
if p == 0:
zeroCumuMoment[p] = grayHist[0]
else:
zeroCumuMoment[p] = zeroCumuMoment[p-1] + grayHist[p]
# 第三步: 根据累加灰度直方图得到输入灰度级和输出灰度级之间的映射关系
outPut_q = np.zeros([256],np.uint8)
cofficient = 256.0/(rows*cols)
for p in range(256):
q = cofficient * float(zeroCumuMoment[p]) - 1
if q >=0:
outPut_q[p] = math.floor(q)
else:
outPut_q[p] = 0;
# 第四步:得到直方图均衡化后的图像
equalHistImage = np.zeros(image.shape,np.uint8)
for r in range(rows):
for c in range(cols):
equalHistImage[r][c] = outPut_q[image[r][c]]
return equalHistImage
if __name__ == "__main__":
I = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
I = equalHist(I)
#显示原图和伽马变换后的效果
cv2.imshow("I",I)
cv2.imshow("O",O)
cv2.waitKey(0)
cv2.destroyAllWindows()
限制对比度的自适应直方图均值化
import cv2
import numpy as np
if __name__ == "__main__":
I = cv2.imread("c:/users/76973/desktop/picture/output_image2.jpg",cv2.IMREAD_GRAYSCALE)
#创建CLAHE对象
clahe = cv2.createCLAHE(clipLimit = 2.0, tileGridSize = (8, 8))
#限制对比度的自适应阈值均衡化
O = clahe.apply(I)
#显示原图和伽马变换后的效果
cv2.imshow("I",I)
cv2.imshow("O",O)
cv2.waitKey(0)
cv2.destroyAllWindows()