我打算编写一个程序来检测和区分某些对象与几乎可靠的背景。前景和背景具有高对比度差异,我将进一步增加以帮助对象识别过程。我打算使用Hough变换技术和OpenCV。
如上图所示,我想分别识别圆形物体和方形物体(或有限形状的任何其他形状)。由于我对图像处理很陌生,我不知道这种情况是否需要实现神经网络以及预先学习每个形状。如果没有神经网络,模板匹配等技术会让我这样做吗?
答案 0 :(得分:10)
这些帖子可以帮助您入门:
您可能需要调整这些代码中的一些参数以匹配您的圆圈/方块,但这些示例中显示了该技术的核心。
答案 1 :(得分:9)
如果您打算检测除圆形之外的形状(并且从我假设您的图像中),我建议您快速启动倒角匹配,特别是当您具有良好的对比度时
以简单的术语解释的基本前提如下:
cvCanny
)这种基本方法是一种通用解决方案,通常效果很好,但没有进一步的改进,它的速度非常慢。
通常首先分离感兴趣的对象是个好主意,因此您不必总是对整个图像进行完整搜索。找到一个好的threshold
,这样你就可以分开对象了。你仍然不知道它是哪个对象,但你只需要在这个对象附近进行匹配。
另一个好主意是,不要在高分辨率图像上进行全面搜索,而是首先以非常低的分辨率进行搜索。结果不会非常准确,但您可以了解在更高分辨率下搜索的一般区域,这样您就不会在没有任何兴趣的区域浪费您的时间。
有许多更先进的技术,但仍然值得看一下基本的倒角匹配,因为它是大量技术的基础。
答案 2 :(得分:0)
假设对象是简单形状,这是一种使用阈值+轮廓近似的方法。轮廓近似是基于这样的假设,即曲线可以由一系列短线段近似,这些短线段可用于确定轮廓的形状。例如,三角形有三个顶点,正方形/矩形有四个顶点,五边形有五个顶点,依此类推。
获得二进制图像。我们加载图像,转换为灰度,高斯模糊,然后adaptive threshold以获得二进制图像。
检测形状。使用轮廓近似过滤查找轮廓并标识每个轮廓的形状。可以使用arcLength
来计算轮廓的周长,并使用approxPolyDP
来获得实际的轮廓近似值。
输入图片
检测到的对象以绿色突出显示
标记轮廓
代码
import cv2
def detect_shape(c):
# Compute perimeter of contour and perform contour approximation
shape = ""
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
# Triangle
if len(approx) == 3:
shape = "triangle"
# Square or rectangle
elif len(approx) == 4:
(x, y, w, h) = cv2.boundingRect(approx)
ar = w / float(h)
# A square will have an aspect ratio that is approximately
# equal to one, otherwise, the shape is a rectangle
shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
# Star
elif len(approx) == 10:
shape = "star"
# Otherwise assume as circle or oval
else:
shape = "circle"
return shape
# Load image, grayscale, Gaussian blur, and adaptive threshold
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,31,3)
# Find contours and detect shape
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
# Identify shape
shape = detect_shape(c)
# Find centroid and label shape name
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cv2.putText(image, shape, (cX - 20, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 2)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()