我已经使用vec4i在一个4元素向量整数数组中存储了使用凸性缺陷的缺陷。
我的凸船体数组在船体元素和轮廓在轮廓;我要做的是画一条线从一个凸缺陷的起点到一个凸缺陷的终点。为此,我需要访问元素开始索引,它存在于缺陷向量的vec4i中!
我该怎么做??
#include <opencvcv.h>
#include <opencv2highguihighgui.hpp>
#include<opencvcvaux.h>
#include<opencvcxcore.h>
#include <opencv2imgprocimgproc.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(..)行时,我的输出窗口也显示错误,我认为这是错误的格式!
convexityDefects需要一个
使用convexHull()获得的凸船体,该凸船体应包含构成船体的轮廓点的索引。
包含超过3个索引。所以你需要这个:
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]);
}
}
那么你的绘图部分是(从这里改编):
/// 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 <opencv2opencv.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;
}
}