小言_互联网的博客

在OpenCV里实现图像线性变换

685人阅读  评论(0)

在前面学习了什么叫做灰度直方图,知道图像对比度是通过灰度级范围来度量的,而灰度级范围可通过观察灰度直方图得到,范围越大说明对比度越高。低对比度的图像在视觉上给人的感觉是看起来不够清晰,因此需要通过算法来调整图像的灰度值,从而使用图像更加清晰起来,最容易理解的算法就是线性变换的算法。对于图像矩阵的线性变换,无非就是乘一个常数,或者每个值加上常数。如果大于255的值转换为255,这样就可以限制图像的像素值不会超过显示范围。

我们知道线性变换的方程为y=ax+b,在下面这个例子里,先假定b等于0,a可以取大于0的值,代码如下:

#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

#图片的路径
imgname = "imgblack.jpg"

#读取图片
image = cv2.imread(imgname, cv2.IMREAD_GRAYSCALE)

#图片的高度和宽度
h,w = image.shape[:2]
print(w,h)

#显示原图
cv2.imshow("Image",image)

#线性变换处理
m = 2.25
outline = m*image
print(np.max(outline))
outline[outline>255] = 255
outline = np.round(outline)
outline = outline.astype(np.uint8)

cv2.imshow("outline", outline)

#显示直方图
pixel = outline.reshape([h*w,])#把二维数组转换为一维数组
grayHist, bins, patch = plt.hist(pixel, 256,facecolor='black',histtype='bar')
plt.xlabel('灰度值')
plt.ylabel('像素个数')
plt.axis([0,255, 0, np.max(grayHist)])#设置坐标轴范围
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()
    

结果输出如下:

左图是输入图片,有点偏暗,右图是线性变换之后图片

线性变换之后的灰度直方图

 

从上面图像对比之后,发现图片变换之后,对比度好看了好多。现在继续分析一下例子里线性变换的那段代码。

#线性变换处理

m = 2.25

outline = m*image

print(np.max(outline))

outline[outline>255] = 255

outline = np.round(outline)

outline = outline.astype(np.uint8)

在这里m定义了比例放大系数,相当于公式里的a值,接着在m*image里与图像矩阵相乘,这样图像的每个像素都放大了。outline[outline>255] 是numpy数组的布尔索引的用法,相当于找出数组里所有大于255的元素,然后把右边的值255赋值。np.round()是对数组进行最近值取整,比如1.5和2.5运算之后为2.0。由于数组在前面进行相乘之后,元素的数据类型转换为浮点型,因此在最后使用outline.astype()转换为8位整型。这里使用的运算都是numpy的知识,所以要对numpy先行学习,才能继续学习下去。

 


转载:https://blog.csdn.net/caimouse/article/details/100520827
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场