OpenCV凸性缺陷绘图 [英] OpenCV convexity defects drawing

查看:217
本文介绍了OpenCV凸性缺陷绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用vec4i在4元素向量整数数组中存储了使用凸面缺陷的缺陷。

I have stored the defects using convexity defects in an 4 element vector integer array using vec4i.

我的凸包数组是在轮廓中的轮廓元素和轮廓;
我想做的是绘制一条线从一个凸性缺陷的起点到一个终点。
对于这个我需要访问存在于缺陷矢量的vec4i中的元素开始索引!

My convex hull array is in hull element and contours in Contours; What i want to do is draw a line from start point of a convexity defect to the end point of one. For this i need to access the element start index which is present in the vec4i of a defects vector!

我如何做这个?

   #include <opencv\cv.h>
#include <opencv2\highgui\highgui.hpp>
#include<opencv\cvaux.h>
#include<opencv\cxcore.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
#include<conio.h>
#include <stdlib.h>



using namespace cv;
using namespace std;

int main(){


    Mat img, frame, img2, img3;


    VideoCapture cam(0);
    while (true){
        cam.read(frame);
        cvtColor(frame, img, CV_BGR2HSV);
        //thresholding 
        inRange(img, Scalar(0, 143, 86), Scalar(39, 255, 241), img2);

        imshow("hi", img2);

        //finding contours
        vector<vector<Point>> Contours;
        vector<Vec4i> hier;
        //morphological transformations
        erode(img2, img2, getStructuringElement(MORPH_RECT, Size(3, 3)));
        erode(img2, img2, getStructuringElement(MORPH_RECT, Size(3, 3)));

        dilate(img2, img2, getStructuringElement(MORPH_RECT, Size(8, 8)));
        dilate(img2, img2, getStructuringElement(MORPH_RECT, Size(8, 8)));


        //finding the contours required
        findContours(img2, Contours, hier, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, Point(0, 0));



        //finding the contour of largest area and storing its index
        int lrgctridx = 0;
        int maxarea = 0;
        for (int i = 0; i < Contours.size(); i++)
        {
            double a = contourArea(Contours[i]);
            if (a> maxarea)
            {
                maxarea = a;
                lrgctridx = i;
            }

        }
        //convex hulls
        vector<vector<Point> >hull(Contours.size());
        vector<vector<Vec4i>> defects(Contours.size());
        for (int i = 0; i < Contours.size(); i++)
        {
            convexHull(Contours[i], hull[i], false);
            convexityDefects(Contours[i], hull[i], defects[i]);
        }
        //REQUIRED contour is detected,then convex hell is found and also convexity defects are found and stored in defects




        if (maxarea>100){
            drawContours(frame, hull, lrgctridx, Scalar(255, 255, 255), 1, 8, vector<Vec4i>(), 0, Point());
        \\ drawing the required lines joining defects!im facing problem on how to acheive this since i dont know how to access the elements stored in defects
           line(frame, \\startindex, \\endindex, \\color, 1);

        }


        imshow("output", frame);
        char key = waitKey(33);
        if (key == 27) break;



    }

}

此外,我的输出窗口显示错误时,我添加了convexityDefects(..)行,我认为它是错误的格式!
提前感谢。

Also my output window shows error when i add the convexityDefects(..) line i think it is in wrong format! Thanks in advance.

推荐答案

convexityDefects 需要


使用convexHull (),它应该包含构成外壳的轮廓点的索引。

Convex hull obtained using convexHull() that should contain indices of the contour points that make the hull.

包含多于3个索引。所以你需要这个:

that contains more than 3 indices. So you need this:

vector<vector<Point> >hull(Contours.size());
vector<vector<int> > hullsI(Contours.size()); // Indices to contour points
vector<vector<Vec4i>> defects(Contours.size());
for (int i = 0; i < Contours.size(); i++)
{
    convexHull(Contours[i], hull[i], false);
    convexHull(Contours[i], hullsI[i], false); 
    if(hullsI[i].size() > 3 ) // You need more than 3 indices          
    {
        convexityDefects(Contours[i], hullsI[i], defects[i]);
    }
}

然后你的绘图部分=http://stackoverflow.com/a/14137154/5008845>此处):

Then your drawing part is (adapted from here):

/// Draw convexityDefects
for (int i = 0; i < Contours.size(); ++i)
{
    for(const Vec4i& v : defects[i])
    {
        float depth = v[3] / 256;
        if (depth > 10) //  filter defects by depth, e.g more than 10
        {
            int startidx = v[0]; Point ptStart(Contours[i][startidx]);
            int endidx = v[1]; Point ptEnd(Contours[i][endidx]);
            int faridx = v[2]; Point ptFar(Contours[i][faridx]);

            line(frame, ptStart, ptEnd, Scalar(0, 255, 0), 1);
            line(frame, ptStart, ptFar, Scalar(0, 255, 0), 1);
            line(frame, ptEnd, ptFar, Scalar(0, 255, 0), 1);
            circle(frame, ptFar, 4, Scalar(0, 255, 0), 2);
        }
    }
}   

完成代码

#include <opencv2\opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    Mat img, frame, img2, img3;
    VideoCapture cam(0);
    while (true){
        cam.read(frame);

        cvtColor(frame, img, CV_BGR2HSV);

        //thresholding 
        inRange(img, Scalar(0, 143, 86), Scalar(39, 255, 241), img2);

        imshow("hi", img2);

        //finding contours
        vector<vector<Point>> Contours;
        vector<Vec4i> hier;
        //morphological transformations
        erode(img2, img2, getStructuringElement(MORPH_RECT, Size(3, 3)));
        erode(img2, img2, getStructuringElement(MORPH_RECT, Size(3, 3)));

        dilate(img2, img2, getStructuringElement(MORPH_RECT, Size(8, 8)));
        dilate(img2, img2, getStructuringElement(MORPH_RECT, Size(8, 8)));

        //finding the contours required
        findContours(img2, Contours, hier, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, Point(0, 0));

        //finding the contour of largest area and storing its index
        int lrgctridx = 0;
        int maxarea = 0;
        for (int i = 0; i < Contours.size(); i++)
        {
            double a = contourArea(Contours[i]);
            if (a> maxarea)
            {
                maxarea = a;
                lrgctridx = i;
            }
        }
        //convex hulls
        vector<vector<Point> >hull(Contours.size());
        vector<vector<int> > hullsI(Contours.size()); 
        vector<vector<Vec4i>> defects(Contours.size());
        for (int i = 0; i < Contours.size(); i++)
        {
            convexHull(Contours[i], hull[i], false);
            convexHull(Contours[i], hullsI[i], false); 
            if(hullsI[i].size() > 3 )            
            {
                convexityDefects(Contours[i], hullsI[i], defects[i]);
            }
        }
        //REQUIRED contour is detected,then convex hell is found and also convexity defects are found and stored in defects

        if (maxarea>100){
            drawContours(frame, hull, lrgctridx, Scalar(2555, 0, 255), 3, 8, vector<Vec4i>(), 0, Point());

            /// Draw convexityDefects
            for(int j=0; j<defects[lrgctridx].size(); ++j)
            {
                const Vec4i& v = defects[lrgctridx][j];
                float depth = v[3] / 256;
                if (depth > 10) //  filter defects by depth
                {
                    int startidx = v[0]; Point ptStart(Contours[lrgctridx][startidx]);
                    int endidx = v[1]; Point ptEnd(Contours[lrgctridx][endidx]);
                    int faridx = v[2]; Point ptFar(Contours[lrgctridx][faridx]);

                    line(frame, ptStart, ptEnd, Scalar(0, 255, 0), 1);
                    line(frame, ptStart, ptFar, Scalar(0, 255, 0), 1);
                    line(frame, ptEnd, ptFar, Scalar(0, 255, 0), 1);
                    circle(frame, ptFar, 4, Scalar(0, 255, 0), 2);
                }
            }
        }

        imshow("output", frame);
        char key = waitKey(33);
        if (key == 27) break;

    }
}

这篇关于OpenCV凸性缺陷绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆