代码之家  ›  专栏  ›  技术社区  ›  der_napf

在没有固定角度的图像上绘制旋转的边界框

  •  1
  • der_napf  · 技术社区  · 7 年前

    我不熟悉编程和opencv,我尝试使用颜色分割检测硬盘。到目前为止,我的代码加载了一个图像,创建了3个不同颜色的遮罩,并在非零点周围绘制了一个垂直边界框:

    int main( int argc, char** argv )
    {
    
    //Load the image
    Mat img = imread(argv[1], 1);
    if (img.empty()){
    cout << "No image found..." << endl;
    return -1;
    }
    
    //Extracting colors - BGR
    Mat silver, white, black;
    
    //Silver
    inRange(img, Scalar(180, 180, 180), Scalar(200, 200, 200), silver);
    
    //White
    inRange(img, Scalar(240, 240, 240), Scalar(255, 255, 255), white);
    
    //Black
    inRange(img, Scalar(0, 0, 0), Scalar(30, 30, 30), black);
    
    // logical OR mask
    Mat1b mask = silver | white | black;
    
    // Find non zero pixels
    vector<Point> pts;
    
    findNonZero(mask, pts);
    
    cout << "Non-Zero Locations = " << pts << endl << endl; // get non zero coordinates
    
    // Compute bounding box
    
    Rect box = boundingRect(pts);
    
    // Show bounding box
    rectangle(img, box, Scalar(0, 0, 255), 3);
    namedWindow("box", CV_WINDOW_NORMAL);
    imshow("box", img); 
    imshow("mask", mask);
    
    waitKey(0);
    destroyAllWindows;
    
    return 0;}
    

    cv::RotatedRect box2 = cv::minAreaRect(pts);
    

    相反但当我试图通过替换

    Rect box = boundingRect(pts); 
    

    具有

    RotatedRect box2 = minAreaRect(pts);
    

    错误输出:

    error: no matching function for call to ‘rectangle(cv::Mat&, cv::RotatedRect&, cv::Scalar, int)’
     rectangle(img, box2, Scalar(0, 0, 255), 3);
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   ZdaR    7 年前

    根据 cv::Rectangle Opencv Docs ,该功能只有两种变体:

    void rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
    
    void rectangle(Mat& img, Rect rec, const Scalar& color, int thickness=1, int lineType=8, int shift=0 )
    

    所以很明显,它只接受其中之一 cv::Rect cv::Point . 因此,没有规定直接输入 cv::RotatedRect ,因此会出现上述错误。

    要解决此问题,可以提取 cv::RotatedRect 使用:

    cv::Point2f points[4];
    rotatedRect.points(points);
    

    然后使用 cv::line() 将边成对绘制为:

    cv::RotatedRect rotatedRect = cv::RotatedRect(cv::Point(70, 70), cv::Size(90, 90), 30);
    
    cv::Mat canvas = cv::Mat(200, 200, CV_8UC3, cv::Scalar(255, 255, 255));
    
    cv::Point2f points[4];
    rotatedRect.points(points);
    
    cv::line(canvas, points[0], points[1], cv::Scalar(0, 255, 0), 3);
    cv::line(canvas, points[1], points[2], cv::Scalar(0, 255, 0), 3);
    cv::line(canvas, points[2], points[3], cv::Scalar(0, 255, 0), 3);
    cv::line(canvas, points[3], points[0], cv::Scalar(0, 255, 0), 3);
    

    enter image description here