<p>这是我拍摄的一个简单的算法,用于清理特定的图像。可以随意使用它,并进一步调整它,以获得所需的结果。</p>
<p><strong>NB</strong>:显示的代码应该同时适用于OpenCV的2.4.x和3.x分支。</p>
<h2>步骤0</h2>
<p>将输入图像加载为灰度。</p>
<pre><code>img = cv2.imread('paper.jpg',0)
</code></pre>
<h2>步骤1</h2>
<p>放大图像,以便去掉文本。
这一步有助于保留条形码。</p>
<pre><code>dilated_img = cv2.dilate(img, np.ones((7,7), np.uint8))
</code></pre>
<p><a href="https://i.stack.imgur.com/zb0r3.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/zb0r3.jpg" alt="Dilated"/></a></p>
<h2>步骤2</h2>
<p>中值模糊结果与一个像样的大小内核,以进一步抑制任何文本。</p>
<p>这会给我们一个相当好的背景图像,包含所有的阴影和/或变色。</p>
<pre><code>bg_img = cv2.medianBlur(dilated_img, 21)
</code></pre>
<p><a href="https://i.stack.imgur.com/5T3Td.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/5T3Td.jpg" alt="Blurred"/></a></p>
<h2>步骤3</h2>
<p>计算原始图像和我们刚刚得到的背景之间的差异。相同的位将是黑色(接近0差),文本将是白色(大差)。</p>
<p>既然我们要黑对白,我们就把结果颠倒过来。</p>
<pre><code>diff_img = 255 - cv2.absdiff(img, bg_img)
</code></pre>
<p><a href="https://i.stack.imgur.com/ZqKNP.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/ZqKNP.jpg" alt="Inverted Difference"/></a></p>
<h2>步骤4</h2>
<p>将图像规格化,以便使用完整的动态范围。</p>
<pre><code>norm_img = diff_img.copy() # Needed for 3.x compatibility
cv2.normalize(diff_img, norm_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
</code></pre>
<p><a href="https://i.stack.imgur.com/ZrRFI.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/ZrRFI.jpg" alt="Normalized"/></a></p>
<h2>步骤5</h2>
<p>现在我们的报纸还是有些灰色。我们可以将其截断,然后重新规范化图像。</p>
<pre><code>_, thr_img = cv2.threshold(norm_img, 230, 0, cv2.THRESH_TRUNC)
cv2.normalize(thr_img, thr_img, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
</code></pre>
<p><a href="https://i.stack.imgur.com/eM3Gn.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/eM3Gn.jpg" alt="Gray Trimmed"/></a></p>
<p>完成。。。</p>
<p>好吧,至少对我来说是这样;)你可能会想修剪它,然后做任何你想做的后处理。</p>
<hr/>
<p>注意:在得到差分图像后,可能需要切换到更高的精度(16位int或float),以最小化重复规格化中累积的舍入误差。</p>