去除照片中的闪光,使用OpenCV。

23

所以,我正在使用OpenCV来捕获文档,扫描它并裁剪它。当房间没有照明时,它可以完美地工作。当房间里有一些光线,并且桌子上有眩光,文档靠近它时,它也会将眩光作为矩形的一部分捕获。

如何从照片中去除眩光?

这是我用来获取所需图像的代码:

 Mat &image = *(Mat *) matAddrRgba;
    Rect bounding_rect;

    Mat thr(image.rows, image.cols, CV_8UC1);
    cvtColor(image, thr, CV_BGR2GRAY); //Convert to gray
    threshold(thr, thr, 150, 255, THRESH_BINARY + THRESH_OTSU); //Threshold the gray

    vector<vector<Point> > contours; // Vector for storing contour
    vector<Vec4i> hierarchy;
    findContours(thr, contours, hierarchy, CV_RETR_CCOMP,
                 CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image
    sort(contours.begin(), contours.end(),
         compareContourAreas);            //Store the index of largest contour
    bounding_rect = boundingRect(contours[0]);

    rectangle(image, bounding_rect, Scalar(250, 250, 250), 5);

这里是我所说的反光照片:

在此输入图片描述

我发现可以使用inRange函数,查找适当的颜色标量并使用inpaint函数消除光线。这是相关代码片段,但它总是崩溃,显示需要具有通道的8位图像。

Mat &image = *(Mat *) matAddrRgba;

    Mat hsv, newImage, inpaintMask;
    cv::Mat lower_red_hue_range;
    inpaintMask = Mat::zeros(image.size(), CV_8U);
    cvtColor(image, hsv, COLOR_BGR2HSV);
    cv::inRange(hsv, cv::Scalar(0, 0, 215, 0), cv::Scalar(180, 255, 255, 0),
                lower_red_hue_range);
    image = lower_red_hue_range;

    inpaint(image, lower_red_hue_range, newImage, 3, INPAINT_TELEA);

您可以尝试从不同角度拍摄3-4张照片,以克服桌子上的反光效果。 - ZdaR
1
如果你不回答问题,你知道这会很困难。 - Rick M.
Glare非常类似于消除镜头耀斑的技术,简单来说,它们向RGB色彩空间中添加内容,使其接近最大值。这种分布可能比较复杂,您可能需要使用空间滤波器来确保尽可能保持背景逼真。对于这种情况,有一个洋葱皮方法,您可以从一个3x3矩阵集合开始,去除额外的耀斑成分,并以洋葱皮的方式向中心移动。您可以运行它来查找是否遵循耀斑模式并删除它。 - Farrukh Subhani
当房间里没有灯光时,它可以完美地工作。- 当然,它是完全黑色的 :D - hans
2个回答

21

我曾经也遇到过这个问题,光照变化总是计算机视觉检测和图像描述的一个问题。我实际上训练了一个分类器,用HSV颜色空间代替RGB / BGR,将具有光照变化的图像映射为没有突然亮度/暗斑点的图像(这将是标签)。这对我来说效果很好,但是图像始终是相同背景的(不知道你是否也有这种情况)。

当然,机器学习可以解决这个问题,但可能有些过度。在我进行上述操作时,我遇到了CLAHE,它对于局部对比度增强效果非常好。我建议您在检测轮廓之前尝试使用它。此外,您可能需要使用不同的颜色空间,如HSV / Lab / Luv而不是RGB / BGR来完成此目的。您可以将CLAHE分别应用于每个通道,然后合并它们。

如果您需要其他信息,请告诉我。我在Python中使用您的图像实现了这一点,效果非常好,但我会留下编码给您。我可能会在几天后更新我得到的结果(希望您能先看到它们;))。希望对您有所帮助。

灰度图像

经过CLAHE处理的HSV中的V通道-clipLimit = 10,TileGridSize =(16,16)


@JeruLuke 你尝试在HSV颜色空间中使用不同的参数了吗? - Rick M.
让我们看看它是否能帮助原帖作者,他似乎并不太在意。只是在问题上获得了赞数。 - Rick M.
1
@MiljanVulovic 感谢您接受我的答案,但由于您迟迟未予认可,我无法获得悬赏积分。 - Rick M.
1
ri@RickM。好东西。谢谢。 - Andrew Simpson

7

OpenCV-Python助手

输入图像

 import cv2
 import numpy as np
 import time


clahefilter = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(16,16))


img = cv2.imread('spects_glare.jpg')

while True:
t1 = time.time() 
img = img.copy()

## crop if required 
#FACE
x,y,h,w = 550,250,400,300
# img = img[y:y+h, x:x+w]

#NORMAL
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
grayimg = gray


GLARE_MIN = np.array([0, 0, 50],np.uint8)
GLARE_MAX = np.array([0, 0, 225],np.uint8)

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

#HSV
frame_threshed = cv2.inRange(hsv_img, GLARE_MIN, GLARE_MAX)


#INPAINT
mask1 = cv2.threshold(grayimg , 220, 255, cv2.THRESH_BINARY)[1]
result1 = cv2.inpaint(img, mask1, 0.1, cv2.INPAINT_TELEA) 



#CLAHE
claheCorrecttedFrame = clahefilter.apply(grayimg)

#COLOR 
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
lab_planes = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
lab_planes[0] = clahe.apply(lab_planes[0])
lab = cv2.merge(lab_planes)
clahe_bgr = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)


#INPAINT + HSV
result = cv2.inpaint(img, frame_threshed, 0.1, cv2.INPAINT_TELEA) 


#INPAINT + CLAHE
grayimg1 = cv2.cvtColor(clahe_bgr, cv2.COLOR_BGR2GRAY)
mask2 = cv2.threshold(grayimg1 , 220, 255, cv2.THRESH_BINARY)[1]
result2 = cv2.inpaint(img, mask2, 0.1, cv2.INPAINT_TELEA) 



#HSV+ INPAINT + CLAHE
lab1 = cv2.cvtColor(result, cv2.COLOR_BGR2LAB)
lab_planes1 = cv2.split(lab1)
clahe1 = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
lab_planes1[0] = clahe1.apply(lab_planes1[0])
lab1 = cv2.merge(lab_planes1)
clahe_bgr1 = cv2.cvtColor(lab1, cv2.COLOR_LAB2BGR)




# fps = 1./(time.time()-t1)
# cv2.putText(clahe_bgr1    , "FPS: {:.2f}".format(fps), (10, 180), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255))    

# display it
cv2.imshow("IMAGE", img)
cv2.imshow("GRAY", gray)
cv2.imshow("HSV", frame_threshed)
cv2.imshow("CLAHE", clahe_bgr)
cv2.imshow("LAB", lab)
cv2.imshow("HSV + INPAINT", result)
cv2.imshow("INPAINT", result1)
cv2.imshow("CLAHE + INPAINT", result2)  
cv2.imshow("HSV + INPAINT + CLAHE   ", clahe_bgr1)


# Break with esc key
if cv2.waitKey(1) & 0xFF == ord('q'): 
    break


cv2.destroyAllWindows()

output


1
opencv-python // 去除眩光工具 - Bharath Kumar
你能具体说明如何首先检测眩光吗? - Deshwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接