opencv中文文档

opencv中文文档


形态变换

<h1>目标</h1> <p>在本文中,</p> <ul> <li>我们将学习不同的形态操作,如侵蚀,膨胀,打开,关闭等。</li> <li>我们将看到不同的函数,如: cv.erode(), cv.dilate(), cv.morphologyEx()等。</li> </ul> <h1>原理</h1> <p>形态学变换是一些基于图像形状的简单操作。它通常在二进制图像上执行。它需要两个输入,一个是原始图像,另一个是决定操作性质的结构化元素或内核。侵蚀和膨胀是两种基本的形态操作符。然后它的变体形式,如打开,关闭,梯度等也发挥作用。我们将看到他们一个一个的帮助下,如下图:</p> <p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/1f387536c53ca41879c932971d6060ed?showdoc=.jpg" alt="" /></p> <h3>1.侵蚀</h3> <p>侵蚀的基本思想就像土壤侵蚀一样,它侵蚀前景对象的边界(总是尽量保持前景为白色)。那么它是做什么的呢?内核在图像中滑动(就像在2D卷积中一样)。只有当内核下的所有像素都是1时,原始图像中的像素(1或0)才会被认为是1,否则就会被侵蚀(变为0)。</p> <p>结果是,所有边界附近的像素都会被丢弃,这取决于内核的大小。因此,前景对象的厚度或大小减小,或只是图像中的白色区域减小。它有助于去除小的白色噪声(正如我们在色彩空间一章中看到的),分离两个连接的物体等。</p> <p>在这里,作为一个例子,我将使用一个包含所有1的5x5内核。让我们看看它是如何工作的:</p> <pre><code class="language-python">import cv2 as cv import numpy as np img = cv.imread('j.png',0) kernel = np.ones((5,5),np.uint8) erosion = cv.erode(img,kernel,iterations = 1)</code></pre> <p>结果: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/93390ecadc342a361a9a473a879ea60a?showdoc=.jpg" alt="" /></p> <h3>2. 膨胀</h3> <p>它正好与侵蚀相反。这里,如果内核下至少有一个像素为1,则像素元素为&quot;1&quot;。所以它增加了图像中的白色区域或前景对象的大小增加。通常,在去除噪音等情况下,侵蚀往往伴随着膨胀。因为,侵蚀消除了白噪音,但也缩小了我们的物体。我们把它放大。因为噪声消失了,它们就不会回来了,但是我们的物体面积增加了。它在连接对象的破碎部分时也很有用。</p> <pre><code class="language-python">dilation = cv.dilate(img,kernel,iterations = 1)</code></pre> <h3>3. 打开</h3> <p>打开只是侵蚀的另一个名称,其次是膨胀。如上所述,它在消除噪声方面很有用。这里我们使用这个函数,cv.morphologyEx()</p> <pre><code class="language-python">opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)</code></pre> <p>结果: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/e7fd1f5a11c89a8b40d65a37ef549f57?showdoc=.jpg" alt="" /></p> <h3>4. 闭合</h3> <p>闭合与打开相反,膨胀伴随着侵蚀。它在关闭前景对象内部的小洞或对象上的小黑点时非常有用。</p> <pre><code class="language-python">closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)</code></pre> <p>结果: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/34c1cdaaa779e26fd79d0f5a9a8129ff?showdoc=.jpg" alt="" /></p> <h3>5. 形态梯度</h3> <p>它是图像膨胀和侵蚀的区别。</p> <p>结果看起来像是对象的轮廓。</p> <pre><code class="language-python">gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)</code></pre> <p>结果: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/abb03cd570ec8a07508f4a9bb3e3f87e?showdoc=.jpg" alt="" /></p> <h3>6. 顶帽</h3> <p>它是输入图像和打开图像之间的区别。下面的示例是针对9x9内核完成的。</p> <pre><code class="language-python">tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)</code></pre> <p>结果: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/483b31eed255ce87ab4d87437ba1c5ec?showdoc=.jpg" alt="" /></p> <h3>7. 黑帽</h3> <p>它是输入图像与输入图像的闭合差。</p> <pre><code class="language-python">blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)</code></pre> <p>结果: <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/5e21012841d35839d26dcf0aef3bcf62?showdoc=.jpg" alt="" /></p> <h1>结构化元素</h1> <p>在前面的示例中,我们在Numpy的帮助下手动创建了一个结构化元素。它是长方形的。但在某些情况下,您可能需要椭圆/圆形内核。为此,OpenCV有一个函数cv.getstructuringelement()。只需传递内核的形状和大小,就可以得到所需的内核。</p> <pre><code class="language-python"># Rectangular Kernel &gt;&gt;&gt; cv.getStructuringElement(cv.MORPH_RECT,(5,5)) array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]], dtype=uint8) # Elliptical Kernel &gt;&gt;&gt; cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)) array([[0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0]], dtype=uint8) # Cross-shaped Kernel &gt;&gt;&gt; cv.getStructuringElement(cv.MORPH_CROSS,(5,5)) array([[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]], dtype=uint8)</code></pre> <h1>其他资源</h1> <p><a href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/morops.htm" title="HIPR2的形态学操作">HIPR2的形态学操作</a></p>

页面列表

ITEM_HTML