检查图像中是否有过薄的区域

2024-10-01 00:36:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试验证雕刻机的黑白图像(更多的是剪贴画图像,而不是照片)。
我需要考虑的一个主要问题是区域的大小(或线条的宽度),因为机器无法处理太细的线条,所以我需要找到比给定阈值更细的区域。在

以这张图片为例:

enter image description here

竖琴的琴弦可能太细,无法雕刻。在

我正在读有关Matlab和OpenCV的文章,但图像处理是我第一次学习的领域。在

我是一个Java/C开发人员,所以用其中一种语言来实现对我来说是最好的,但是任何方向都会非常感谢。在


Tags: 图像机器区域宽度图片阈值照片线条
2条回答

使用利用图像morphological operations的解决方案:

定义允许区域的最小厚度,例如,minThick=4

BW = imread('http://i.stack.imgur.com/oXKep.jpg'); 
BW = BW(:,:,1) < 128; %// convert image to binary mask
se = strel('disk', minTick/2, 0); %// define a disk element   
eBW = imerode( BW, se ); %// "chop" half thickness from mask
deBW = imdilate( eBW, se ); %// dilate the eroded mask

腐蚀和膨胀应使厚度大于minThick的区域保持不变,但它会移除较薄的区域

^{pr2}$

结果是:
enter image description here

您可以在链接文档中阅读有关^{}^{}的更多信息。在

这主要是为了自包含,但这是与@Shai在Python中执行的代码相同的代码。我使用了Python中的^{}OpenCV包。在Python中执行此操作的等效代码如下:

import numpy as np # Import numpy package
import cv2 # Import OpenCV package

orig = cv2.imread('oXKep.jpg') # Read in image from disk
BW = orig[:,:,2] < 128 # Threshold below 128 to invert image
minThick = 5 # Define minimum thickness
se = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (minThick,minThick)) # define a disk element
finalBW = 255*cv2.morphologyEx(BW.astype('uint8'), cv2.MORPH_OPEN, se) # "chop" half thickness from mask and dilate the eroded mask

# Find invalid area
invalidArea = 255*np.logical_and(BW, np.logical_not(finalBW)).astype('uint8') 

# Show original image
cv2.imshow('Original', orig)

# Show opened result
cv2.imshow('Final', finalBW)

# Show invalid lines
cv2.imshow('Invalid Area', invalidArea)

# Wait for user input then close windows
cv2.waitKey(0)
cv2.destroyAllWindows()

我需要指出的几个复杂问题:

  1. OpenCV的imread函数在颜色通道中的读取顺序与MATLAB相反。具体来说,通道是以蓝绿红顺序读入的。这意味着第一个通道是蓝色的,第二个通道是绿色的,第三个通道是红色的。在MATLAB中,这些是按正确的RGB顺序读取的。因为这是灰度图像,所以RGB组件是相同的,所以使用哪个通道并不重要。但是,为了与Shai的方法一致,红色通道正在被访问,因此我们需要通过OpenCV访问图像的最后一个通道。在
  2. MATLAB中结构数为0的disk结构元素本质上是一个菱形。但是,由于OpenCV没有内置这个结构元素,而且我希望生成尽可能少的代码来实现某些功能,所以我可以使用的最接近的是椭圆形状的结构元素。在
  3. 为了使结构元素对称,需要确保大小为奇数,因此我将Shai示例中的大小从4改为5。在
  4. 为了使用OpenCV Python显示图像,图像必须至少是无符号8位整数类型。不支持使用OpenCV显示的二进制图像,因此我人为地生成了二进制图像uint8,并在显示之前将值乘以255。在
  5. 您可以使用形态学开口将腐蚀和扩张操作合并为一个操作。打开旨在删除细线或断开连接较薄但仍保持原始较大对象形状的对象。这是腐蚀的第一点,这样你可以删除这些线,但你会缩小一点对象的面积,然后扩大,以便你可以恢复到原来的大小(主要是)。我通过执行一个通过^{}的形态打开来利用这一点。在

我得到的是:

enter image description here

相关问题 更多 >