前言
之前在做一个工业生产使用的图像处理的软件,图片取样的时候发现由于光照不均导致后续的图像处理的结果准确度大大下降,所以需要建立一个模型来矫正光照不均。
由于取样版是长方形的所以建立的是椭圆模型,而如果是正方形对应建立的模型就应该是圆的模型。
原理
红色为取样框,图像中在椭圆上的像素点亮度值相同,椭圆的长半轴为a, 短半轴为b, 则比例半轴比与图像的长(w)宽(h)比相同,即:
而如果要取得最左上角的点,则需要扩大椭圆,在扩大椭圆的时候需要保持半轴比:
如图,蓝色椭圆可以取到,图像的4个角点的像素点,也可以看到,图片的4个角点的亮度是值时相同的,并且可以得出在原始图像中半轴越长椭圆上的像素点亮度值越低,当半轴趋近于零的时候也就是中心点达到亮度值最强。
而我们要建立的模型图片是中心点最暗,角点最亮,最后将建立好的图片模型与原始图片进行叠加从而实现图片亮度矫正。所以我们建立的模型应该是椭圆半轴越长亮度越强。
椭圆公式为:
带入 w,h 得到:
则通过像素点的坐标位置就可以获得 a^2 值,从而获得亮度值。
归一化与矫正力度
a^2 值可能很大,而像素点的亮度取值范围是 0-255, 所以需要进行归一化。
a^2值取值最大时是图像的4个角点:
带入得到 a^2 最大值为:
a^2 最小值 是趋近于零,可以按照零来计算则,进行归一化后(加入矫正系数L):
矫正系数即为取值范围 0-255, 在模型图片中表示中心点到4个角点亮度差值,而在矫正光照任务中表示图片需要加强亮度值(正数)与 需要削弱的亮度值(负数)的差值。
矫正坐标系
上述所有公式依据如图坐标系中:
而实际我们遍历的时候坐标系是这样的:
所以我们需要简单的矫正一下坐标系:
argX = x - w/2
argY = y - h/2
当传入公式的时候,需要使用 argX, argY,也就是矫正后的。
这里我没有给argY判断正负,因为公式里面有平方,所以正负的结果都是一样。
代码编写
import cv2
import numpy as np
def createModel(w,h,L):
img = np.zeros((h,w,3),np.uint8)
for y in range(h):
for x in range(w):
argX = x - w/2
argY = h/2 - y
img[y][x][:] = ((2*(h*argX)**2+2*(argY*w)**2)/(w*h)**2)*L
cv2.imshow("title",img)
# cv2.imwrite("template.png",img)
cv2.waitKey(0)
createModel(640,480,255)
生成椭圆矫正模型:
当长宽相同时,生成圆形矫正模型:
代码看起来没多少,是因为通过推导出的公式写出来的,省去了很多不必要的中间变量。
模型图片使用
详细代码我就不写了,简单的说一下:
可以根据取样的分辨率生成一份矫正模型图片,当然需要调节的就只有 矫正力度 L , 这个可以通过ps的吸管工具对原图的亮度进行拾取,然后计算中间亮度与角点亮度最大差,即为矫正力度。
当然如果直接使用 cv2.add()
函数进行叠加必然造成亮度整体提升,所以可以现计算一下原始的图像亮度均值,然后叠加后再计算一遍亮度均值,然后作差 ,用 cv2.add()加上负数值,即可实现中间亮度降低,四周亮度提升。