检查图像中太薄的区域

时间:2015-02-02 10:16:27

标签: python matlab opencv image-processing

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

以此图片为例:

enter image description here

竖琴弦可能太薄而无法雕刻。

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

我是一名Java / C#开发人员,所以使用其中一种语言完成的实现对我来说是最好的,但任何方向都会受到高度赞赏。

2 个答案:

答案 0 :(得分:9)

使用使用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更厚的区域,但是它会移除薄区域

invalidArea = BW & ~deBW; %// pixels that are in BW but not in deBW

结果:
enter image description here

您可以在链接文档中详细了解imdilateimerode

答案 1 :(得分:4)

这主要用于自我控制,但这是@Shai在Python中执行的等效代码。我使用了Python的numpyOpenCV包。在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. 您可以使用形态开放将侵蚀和扩张操作合并为一个操作。 Opening旨在删除细线或断开连接较薄但仍保持原始更大对象形状的对象。这是首先要进行侵蚀的点,这样你就可以删除这些线,但是你会根据区域缩小对象,然后进行扩张,这样你就可以将形状恢复到原来的大小(大部分)。我通过cv2.morphologyEx执行形态开放来利用它。
  6. 这就是我得到的:

    enter image description here