如何在OpenCV中从图像中提取条纹区域?

时间:2019-11-13 13:56:18

标签: python opencv image-processing orientation image-segmentation

我正在尝试从这张图片中仅提取条纹区域。

enter image description here

这是我要提取的区域。

enter image description here

可能有多种方法,或者可能是它们的组合。

  1. 使用阈值化,形态学,剪切操作提取条纹
  2. Gabor过滤器
  3. 傅立叶变换

如何从fft2穿透铁皮检测条纹的方向。

import numpy as np
import cv2 
import os
import sys
from matplotlib import pyplot as plt


plt.figure(figsize=(12, 12))
gray = cv2.imread('zebra.jpg',0)    
f = np.fft.fft2(gray)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
imgs_comb = np.hstack([gray,magnitude_spectrum])
plt.axis('off')
plt.title('magnitude_spectrum')
plt.imshow(imgs_comb,cmap='gray')   
plt.show()

这组图像在人行道类型,涂料新近度方面是独特的。通常会磨损涂料。尽管有所有这些变化,FFT图像始终为我提供正确的方向和频率。结果看起来很有希望,因为我可以从视觉上看到图案的频率及其方向(图像中的主要垂直图案)。

我们如何使用fft图像滤除其他区域? 使用其他方法欣赏其他建议。

enter image description here

1 个答案:

答案 0 :(得分:0)

这不是使用fft2,而是使用阈值+形态的方法。这个想法是通过Otsu的阈值获得二进制图像,然后使用形态学检测水平线。从这里,我们将检测到的线条绘制到蒙版上,然后执行其他形态学操作,以将条纹组合成单个轮廓。从这里我们找到边界矩形并提取ROI


大津的阈值->在蒙版上画线

enter image description here enter image description here

->打开/关闭->检测到的ROI ->提取的ROI

enter image description here enter image description here enter image description here

import cv2
import numpy as np

image = cv2.imread('1.jpg')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0 ,255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30,1))
detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(mask, [c], -1, (255,255,255), 5)

mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,5))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=3)
opening = cv2.morphologyEx(close, cv2.MORPH_OPEN, kernel, iterations=2)

x,y,w,h = cv2.boundingRect(opening)
ROI = image[y:y+h, x:x+w]

cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.imshow('opening', opening)
cv2.imshow('ROI', ROI)
cv2.waitKey()