Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用OpenCV在python中进行形状检测_Python_Opencv_Shapes - Fatal编程技术网

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

使用OpenCV在python中进行形状检测,python,opencv,shapes,Python,Opencv,Shapes,我正在做一个项目,在这个项目中,我使用OpenCV来检测形状及其颜色 有5种颜色(红色、绿色、黄色、蓝色和白色)和4种形状(矩形、星形、圆形和心形)。我已经能够可靠地辨别颜色,并且当使用的图像是像这样的绘制图像时,我可以检测形状 使用此代码。注意,该图像仅用于演示,我的代码中的范围值不适用于这些颜色 import cv2 import numpy as np class Shape(): def __init__(self, color, shape, x, y, approx):

我正在做一个项目,在这个项目中,我使用OpenCV来检测形状及其颜色

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

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
这在很大程度上是基于这些问题的答案

然而,当我试图检测实际照片上的形状时,我无法可靠地使用它。我得到的边的数量变化很大。这是一张照片的例子,我需要识别照片上的形状。 我猜这是因为形状边缘的小瑕疵,但我不知道如何用直线近似这些边缘,或者如何可靠地识别圆。要做到这一点,我需要在代码中更改什么?密集的谷歌搜索还没有给我答案,但这可能是因为我在搜索中没有使用正确的术语


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

这是我处理你的图像的代码,代码就可以了

  • 模糊来源
  • Canny边缘检测
  • 找到等高线
  • 轮廓的近似多边形
  • 检查approxPolyDP点的总大小
  • 代码:

    Mat src=imread(“src.jpg”,1);
    Mat-thr,灰色;
    模糊(src,src,大小(3,3));
    CVT颜色(src、灰色、CV_BGr2灰色);
    Canny(灰色,thr,50,190,3,假);
    矢量等值线;
    向量层次;
    findContours(thr.clone()、轮廓、层次、CV_RETR_外部、CV_链_近似_简单、点(0,0));
    向量等高线_多边形(等高线.size());
    向量boundRect(contours.size());
    向量中心(courtos.size());
    Vectoradius(courtous.size());
    向量壳(contours.size());
    对于(int i=0;i15)//检查角点
    drawContours(src,等高线_poly,i,标量(0255,0),2,8,向量(),0,点());//真实对象
    其他的
    drawContours(src,等高线_poly,i,标量(0,0255),2,8,向量(),0,点());//假对象
    //绘制等高线(src、外壳、i、标量(0,0255)、2、8、向量()、0、点());
    //矩形(src,boundRect[i].tl(),boundRect[i].br(),标量(0255,0),2,8,0);
    //圆(src,圆心[i],(int)半径[i],标量(0,0255),2,8,0);
    }
    imshow(“src”,src);
    imshow(“Canny”,thr);
    waitKey();
    

    如果在计算
    近似值时使用大于
    0.01的数值,则效果可能更好。不过,您可能会遇到圆组件的问题,最好单独处理。@Habba尝试一下@Haris,它可能适用于圆和矩形,但星星会被识别吗?或者我应该寻找五边形吗?@Habba如果你没有复杂的形状,你可以继续使用approxPolyDP(),在那里你将有15个更多的点设置用于星形形状,看我得到的,这里绿色是被检测到的形状。@Haris哇,看起来真不错。你能解释一下你做了什么吗?先凸包然后再逼近多边形?还是精明?我已经读过了,但是不知道它对这个问题是否有用。非常感谢!这肯定会帮助我理解如何做这些事情。你能再解释一下第五步吗?谢谢也就是说,您必须检查等高线中有多少个点,这是cv::Point类型的向量。轮廓\多边形包含每个轮廓的角点。这样你就可以确认对象是不是星。这是C++,是Python代码吗?只是好奇我不写c,反正我可以把它转换成python谢谢这太棒了!
    
       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();