回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>当拍摄一张纸时(例如使用手机摄像头),我得到以下结果(左图)(jpg下载<a href="https://i.stack.imgur.com/mY7ep.jpg" rel="noreferrer">here</a>)。所需结果(使用图像编辑软件手动处理)位于右侧:</p>
<p><img src="https://i.stack.imgur.com/mY7epm.jpg" alt=""/>
<img src="https://i.stack.imgur.com/se8hCm.jpg" alt=""/></p>
<p><strong>我想使用openCV处理原始图像,以自动获得更好的亮度/对比度<em>(使背景更白)</strong>。</p>
<p>假设:图像为A4纵向格式(在本主题中,我们不需要对其进行透视扭曲),纸张为白色,文本/图像可能为黑色或彩色。</p>
<p>到目前为止我所做的:</p>
<ol>
<li><p>各种自适应阈值方法,如高斯、OTSU(见OpenCV文档<a href="https://docs.opencv.org/3.4.0/d7/d4d/tutorial_py_thresholding.html" rel="noreferrer">Image Thresholding</a>)。它通常适用于大津:</p>
<pre><code>ret, gray = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
</code></pre>
<p><strong>但它仅适用于灰度图像</strong>,而不直接适用于彩色图像。此外,<strong>输出是二进制的(白色或黑色),这是我不想要的</strong>:我更喜欢保持彩色的非二进制图像作为输出</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/Histogram_equalization" rel="noreferrer">Histogram equalization</a></p>
<ul>
<li>应用于Y(在RGB=>;YUV转换之后)</li>
<li>或应用于V(在RGB=>;HSV变换之后)</li>
</ul>
<p>根据这个<a href="https://stackoverflow.com/a/15009815/1422096">answer</a>(<a href="https://stackoverflow.com/questions/15007304/histogram-equalization-not-working-on-color-image-opencv">Histogram equalization not working on color image - OpenCV</a>)或这个<a href="https://stackoverflow.com/a/38312281/1422096">one</a>(<a href="https://stackoverflow.com/questions/31998428/opencv-python-equalizehist-colored-image">OpenCV Python equalizeHist colored image</a>)的建议:</p>
<pre><code>img3 = cv2.imread(f)
img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2YUV)
img_transf[:,:,0] = cv2.equalizeHist(img_transf[:,:,0])
img4 = cv2.cvtColor(img_transf, cv2.COLOR_YUV2BGR)
cv2.imwrite('test.jpg', img4)
</code></pre>
<p>或HSV:</p>
<pre><code>img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2HSV)
img_transf[:,:,2] = cv2.equalizeHist(img_transf[:,:,2])
img4 = cv2.cvtColor(img_transf, cv2.COLOR_HSV2BGR)
</code></pre>
<p>不幸的是,结果相当糟糕,因为它在局部造成了可怕的微对比度(?)以下内容:</p>
<p><img src="https://i.stack.imgur.com/sfOJdm.jpg" alt=""/></p>
<p>我也试过YCbCr,结果很相似。</p></li>
<li><p>我还尝试了<a href="https://docs.opencv.org/3.1.0/d5/daf/tutorial_py_histogram_equalization.html" rel="noreferrer">CLAHE (Contrast Limited Adaptive Histogram Equalization)</a>使用各种<code>tileGridSize</code>从<code>1</code>到<code>1000</code>:</p>
<pre><code>img3 = cv2.imread(f)
img_transf = cv2.cvtColor(img3, cv2.COLOR_BGR2HSV)
clahe = cv2.createCLAHE(tileGridSize=(100,100))
img_transf[:,:,2] = clahe.apply(img_transf[:,:,2])
img4 = cv2.cvtColor(img_transf, cv2.COLOR_HSV2BGR)
cv2.imwrite('test.jpg', img4)
</code></pre>
<p>但结果也同样糟糕。</p></li>
<li><p>按照问题<a href="https://stackoverflow.com/questions/25008458/how-to-apply-clahe-on-rgb-color-images">How to apply CLAHE on RGB color images</a>中的建议,使用LAB颜色空间执行此CLAHE方法:</p>
<pre><code>import cv2, numpy as np
bgr = cv2.imread('_example.jpg')
lab = cv2.cvtColor(bgr, cv2.COLOR_BGR2LAB)
lab_planes = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(100,100))
lab_planes[0] = clahe.apply(lab_planes[0])
lab = cv2.merge(lab_planes)
bgr = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
cv2.imwrite('_example111.jpg', bgr)
</code></pre>
<p>结果也不好。输出图像:</p>
<p><img src="https://i.stack.imgur.com/fi7Bcm.jpg" alt=""/></p></li>
<li><p>对每个通道分别进行自适应阈值化或直方图均衡化<strong>(R,G,B)不是一个选项,因为它会破坏颜色平衡,如<a href="https://stackoverflow.com/questions/15007304/histogram-equalization-not-working-on-color-image-opencv/15009815">here</a>所述。</p></li>
<li><p>来自<code>scikit-image</code>关于<a href="https://scikit-image.org/docs/dev/auto_examples/color_exposure/plot_equalize.html" rel="noreferrer">Histogram Equalization</a>的教程中的“对比度拉伸”方法:</p>
<blockquote>
<p>the image is rescaled to include all intensities that fall within the 2nd and 98th percentiles</p>
</blockquote>
<p>稍微好一点,但离期望的结果还很远(请参见本问题上方的图片)。</p></li>
</ol>
<hr/>
<p><strong>TL;DR:如何使用OpenCV/Python自动优化一张纸的彩色照片的亮度/对比度?</strong>可以使用什么样的阈值/直方图均衡化/其他技术?</p>