本文介绍了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.

推荐答案

需要

包含多于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凸性缺陷绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 22:43