当前位置:  开发笔记 > 编程语言 > 正文

使用Opencv检测图像中矩形的中心和角度

如何解决《使用Opencv检测图像中矩形的中心和角度》经验,为你挑选了1个好方法。

我的图像如下:

包含许多矩形轮廓的示例图像

我需要找出矩形的数量,每个矩形的中心和测量平行于通过中心的矩形的长边的轴之间的角度,并测量从水平方向逆时针方向的角度.我发现了数量图像中的矩形.我很惊讶地发现了中心和反射角度.通过瞬间找到中心并没有给我正确的答案.

我的代码:

import cv2
import numpy as np 
import sys

img = cv2.imread(str(sys.argv[1]),0)
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy = cv2.findContours(thresh,1,2)



for contour in contours:
    area = cv2.contourArea(contour)
    if area>100000:
        contours.remove(contour)




cnt = contours[0]

epsilon = 0.02*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)

print 'No of rectangles',len(approx)


#finding the centre of the contour
M = cv2.moments(cnt)

cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

print cx,cy

Micka.. 16

这是如何使用openCV的minAreaRect函数完成的.它是用C++编写的,但可能你很容易适应,因为几乎只使用了OpenCV函数.

    cv::Mat input = cv::imread("../inputData/rectangles.png");

    cv::Mat gray;
    cv::cvtColor(input,gray,CV_BGR2GRAY);

    // since your image has compression artifacts, we have to threshold the image
    int threshold = 200;
    cv::Mat mask = gray > threshold;

    cv::imshow("mask", mask);

    // extract contours
    std::vector > contours;
    cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

    for(int i=0; i

得到这个图像:

在此输入图像描述

正如您所看到的,角度可能不是您想要的(因为它们随机使用较长或较小的线作为参考).您可以改为提取矩形的长边并手动计算角度.

如果您选择旋转的rects的较长边并从中计算角度,它看起来像这样:

// choose the longer edge of the rotated rect to compute the angle
        cv::Point2f edge1 = cv::Vec2f(rect_points[1].x, rect_points[1].y) - cv::Vec2f(rect_points[0].x, rect_points[0].y);
        cv::Point2f edge2 = cv::Vec2f(rect_points[2].x, rect_points[2].y) - cv::Vec2f(rect_points[1].x, rect_points[1].y);

        cv::Point2f usedEdge = edge1;
        if(cv::norm(edge2) > cv::norm(edge1))
            usedEdge = edge2;

        cv::Point2f reference = cv::Vec2f(1,0); // horizontal edge


        angle = 180.0f/CV_PI * acos((reference.x*usedEdge.x + reference.y*usedEdge.y) / (cv::norm(reference) *cv::norm(usedEdge)));

给出这个结果,这应该是你要找的!

在此输入图像描述

编辑:看起来操作不使用他发布的输入图像,因为参考矩形中心位于图像之外.

使用此输入(手动重新调整但可能仍然不是最佳):

在此输入图像描述

我得到那些结果(蓝点是op提供的参考矩形中心):

在此输入图像描述

比较参考与检测:

reference (x,y,angle)    detection (x,y,angle)
(320,240,0)              (320, 240, 180) // angle 180 is equal to angle 0 for lines
(75,175,90)              (73.5, 174.5, 90)
(279,401,170)            (279.002, 401.824, 169.992)
(507,379,61)             (507.842, 379.75, 61.1443)
(545,95,135)             (545.75, 94.25, 135)
(307,79,37)              (306.756, 77.8384, 37.1042)

我很乐意看到REAL输入图像,也许结果会更好.



1> Micka..:

这是如何使用openCV的minAreaRect函数完成的.它是用C++编写的,但可能你很容易适应,因为几乎只使用了OpenCV函数.

    cv::Mat input = cv::imread("../inputData/rectangles.png");

    cv::Mat gray;
    cv::cvtColor(input,gray,CV_BGR2GRAY);

    // since your image has compression artifacts, we have to threshold the image
    int threshold = 200;
    cv::Mat mask = gray > threshold;

    cv::imshow("mask", mask);

    // extract contours
    std::vector > contours;
    cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

    for(int i=0; i

得到这个图像:

在此输入图像描述

正如您所看到的,角度可能不是您想要的(因为它们随机使用较长或较小的线作为参考).您可以改为提取矩形的长边并手动计算角度.

如果您选择旋转的rects的较长边并从中计算角度,它看起来像这样:

// choose the longer edge of the rotated rect to compute the angle
        cv::Point2f edge1 = cv::Vec2f(rect_points[1].x, rect_points[1].y) - cv::Vec2f(rect_points[0].x, rect_points[0].y);
        cv::Point2f edge2 = cv::Vec2f(rect_points[2].x, rect_points[2].y) - cv::Vec2f(rect_points[1].x, rect_points[1].y);

        cv::Point2f usedEdge = edge1;
        if(cv::norm(edge2) > cv::norm(edge1))
            usedEdge = edge2;

        cv::Point2f reference = cv::Vec2f(1,0); // horizontal edge


        angle = 180.0f/CV_PI * acos((reference.x*usedEdge.x + reference.y*usedEdge.y) / (cv::norm(reference) *cv::norm(usedEdge)));

给出这个结果,这应该是你要找的!

在此输入图像描述

编辑:看起来操作不使用他发布的输入图像,因为参考矩形中心位于图像之外.

使用此输入(手动重新调整但可能仍然不是最佳):

在此输入图像描述

我得到那些结果(蓝点是op提供的参考矩形中心):

在此输入图像描述

比较参考与检测:

reference (x,y,angle)    detection (x,y,angle)
(320,240,0)              (320, 240, 180) // angle 180 is equal to angle 0 for lines
(75,175,90)              (73.5, 174.5, 90)
(279,401,170)            (279.002, 401.824, 169.992)
(507,379,61)             (507.842, 379.75, 61.1443)
(545,95,135)             (545.75, 94.25, 135)
(307,79,37)              (306.756, 77.8384, 37.1042)

我很乐意看到REAL输入图像,也许结果会更好.

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有