gpt4 book ai didi

python - 使用 OpenCV 在 python 中进行形状检测

转载 作者:太空狗 更新时间:2023-10-30 00:56:04 25 4
gpt4 key购买 nike

我正在开展一个项目,在该项目中我使用 OpenCV 来检测形状及其颜色。

有 5 种颜色(红色、绿色、黄色、蓝色和白色)和 4 种形状(矩形、星形、圆形和心形)。我已经能够可靠地辨别颜色,并且当使用的图像是像 this 这样的绘制图像时,我可以检测到形状。使用此代码。请注意,该图像仅用于演示,我的代码中的范围值不适用于这些颜色。

import cv2
import numpy as np
class Shape():

def __init__(self, color, shape, x, y, approx):
self.color = color
self.shape = shape
self.x = x
self.y = y
self.approx = approx
def closing(mask):
kernel = np.ones((7,7),np.uint8)
closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
return closing

def opening(mask):
kernel = np.ones((6,6),np.uint8)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
return opening

#Define Red
lower_red = np.array([0, 90, 60], dtype=np.uint8)
upper_red = np.array([10, 255, 255], dtype=np.uint8)
red = [lower_red, upper_red, 'red']

#Define Green
lower_green = np.array([60, 55, 0], dtype=np.uint8)
upper_green = np.array([100, 255, 120], dtype=np.uint8)
green = [lower_green, upper_green, 'green']

#Define Blue
lower_blue = np.array([90, 20, 60], dtype=np.uint8)
upper_blue = np.array([130, 255, 180], dtype=np.uint8)
blue = [lower_blue, upper_blue, 'blue']

#Define Yellow
lower_yellow = np.array([5, 110, 200], dtype=np.uint8)
upper_yellow = np.array([50, 255, 255], dtype=np.uint8)
yellow = [lower_yellow, upper_yellow, 'yellow']

#Define White
lower_white = np.array([0, 90, 60], dtype=np.uint8)
upper_white = np.array([10, 255, 255], dtype=np.uint8)
white = [lower_white, upper_white ,'white']

colors = [red, green, blue, yellow, white]

def detect_shapes(image_location):
#Open image
img = cv2.imread(image_location)

#Convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

#Shape list
shapes = []

#Lay over masks and detect shapes
for color in colors:
mask = cv2.inRange(hsv, color[0], color[1])
mask = closing(mask)
mask = opening(mask)
contours, h = cv2.findContours(mask, 1, cv2.CHAIN_APPROX_SIMPLE)
contours.sort(key = len)
for contour in contours[-3:]:
#Amount of edges
approx = cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour, True), True)
#Center locations
M = cv2.moments(contour)
if M['m00'] == 0.0:
continue
centroid_x = int(M['m10']/M['m00'])
centroid_y = int(M['m01']/M['m00'])

if len(approx) == 4:
shape_name = 'rectangle'
elif len(approx) == 10:
shape_name = 'star'
elif len(approx) >= 11:
shape_name = 'oval'
else:
shape_name ='undefined'

shape = Shape(color[2], shape_name, centroid_x, centroid_y, len(approx))
shapes.append(shape)

return shapes

这主要基于 this question 上的答案.

但是,当我尝试检测实际照片上的形状时,我无法可靠地使用它。我得到的边缘数量变化很大。 This是我需要识别其形状的照片示例。我猜这是因为形状边缘的小瑕疵造成的,但我无法弄清楚如何用直线近似这些边缘,或者如何可靠地识别圆圈。我需要在代码中更改什么才能执行此操作?密集的谷歌搜索还没有给我答案,但这可能是因为我没有在搜索中使用正确的术语......

另外,如果这个问题的格式不正确,请告诉我!

最佳答案

这是我处理你的图片的代码,代码会做

  1. 模糊来源
  2. Canny 边缘检测。
  3. 找到轮廓。
  4. 轮廓的 approxPolyDP。
  5. 检查 approxPolyDP 点的总大小。

Code:

   Mat src=imread("src.jpg",1);
Mat thr,gray;
blur(src,src,Size(3,3));
cvtColor(src,gray,CV_BGR2GRAY);
Canny(gray,thr,50, 190, 3, false );
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( thr.clone(),contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));

vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect( contours.size() );
vector<Point2f>center( contours.size() );
vector<float>radius( contours.size() );
vector<vector<Point> >hull( contours.size() );
for( int i = 0; i < contours.size(); i++ )
{
approxPolyDP( Mat(contours[i]), contours_poly[i], 10, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
convexHull( Mat(contours[i]), hull[i], false );

if( contours_poly[i].size()>15) // Check for corner
drawContours( src, contours_poly, i, Scalar(0,255,0), 2, 8, vector<Vec4i>(), 0, Point() ); // True object
else
drawContours( src, contours_poly, i, Scalar(0,0,255), 2, 8, vector<Vec4i>(), 0, Point() ); // false object
//drawContours( src, hull, i, Scalar(0,0,255), 2, 8, vector<Vec4i>(), 0, Point() );
// rectangle( src, boundRect[i].tl(), boundRect[i].br(), Scalar(0,255,0), 2, 8, 0 );
//circle( src, center[i], (int)radius[i], Scalar(0,0,255), 2, 8, 0 );
}
imshow("src",src);
imshow("Canny",thr);
waitKey();

enter image description here enter image description here

关于python - 使用 OpenCV 在 python 中进行形状检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22023923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com