【发布时间】:2017-12-27 22:09:52
【问题描述】:
我有下面的 C++ 代码,它旨在从预先指定的图像中检测形状并围绕形状的周边进行绘制。但是,我希望将其带到下一步,并从相机馈送中跟踪形状,而不仅仅是图像。但是,我不熟悉如何进行这种转换。
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
int main()
{
IplImage* img = cvLoadImage("C:/Users/Ayush/Desktop/FindingContours.png");
//show the original image
cvNamedWindow("Raw");
cvShowImage("Raw", img);
//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1);
cvCvtColor(img, imgGrayScale, CV_BGR2GRAY);
//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale, imgGrayScale, 128, 255, CV_THRESH_BINARY);
CvSeq* contours; //hold the pointer to a contour in the memory block
CvSeq* result; //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours
//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
//iterating through each contour
while (contours) {
//obtain a sequence of points of contour, pointed by the variable 'contour'
result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);
//if there are 3 vertices in the contour(It should be a triangle)
if (result->total == 3) {
//iterating through each point
CvPoint *pt[3];
for (int i = 0; i < 3; i++) {
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}
//drawing lines around the triangle
cvLine(img, *pt[0], *pt[1], cvScalar(255, 0, 0), 4);
cvLine(img, *pt[1], *pt[2], cvScalar(255, 0, 0), 4);
cvLine(img, *pt[2], *pt[0], cvScalar(255, 0, 0), 4);
}
//if there are 4 vertices in the contour(It should be a quadrilateral)
else if (result->total == 4) {
//iterating through each point
CvPoint *pt[4];
for (int i = 0; i < 4; i++) {
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}
//drawing lines around the quadrilateral
cvLine(img, *pt[0], *pt[1], cvScalar(0, 255, 0), 4);
cvLine(img, *pt[1], *pt[2], cvScalar(0, 255, 0), 4);
cvLine(img, *pt[2], *pt[3], cvScalar(0, 255, 0), 4);
cvLine(img, *pt[3], *pt[0], cvScalar(0, 255, 0), 4);
}
//if there are 7 vertices in the contour(It should be a heptagon)
else if (result->total == 7) {
//iterating through each point
CvPoint *pt[7];
for (int i = 0; i < 7; i++) {
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}
//drawing lines around the heptagon
cvLine(img, *pt[0], *pt[1], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[1], *pt[2], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[2], *pt[3], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[3], *pt[4], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[4], *pt[5], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[5], *pt[6], cvScalar(0, 0, 255), 4);
cvLine(img, *pt[6], *pt[0], cvScalar(0, 0, 255), 4);
}
//obtain the next contour
contours = contours->h_next;
}
//show the image in which identified shapes are marked
cvNamedWindow("Tracked");
cvShowImage("Tracked", img);
cvWaitKey(0); //wait for a key press
//cleaning up
cvDestroyAllWindows();
cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&imgGrayScale);
return 0;
}
我们非常感谢您对此事的任何帮助。谢谢!
【问题讨论】:
-
如果您使用的是 C++,我将首先重写它以使用 C++ OpenCV API,而不是旧的 C API。
-
然后,重构这个,所以你有一个函数来获取图像,进行处理,然后返回处理后的图像(基本上你在这两次调用
cvShowIMage之间有什么。| 然后考虑视频只是一系列图像,因此您只需不断重复“获取下一帧”、“处理它”、“对结果进行处理”。 -
我已经尝试进行一些更改,但我相信某些元素仍然天生就有错误,而且可能还有很多其他问题。
-
是的,使用
vectors 作为轮廓和层次结构——查看this OpenCV tutorial
标签: c++ visual-studio-2010 opencv video-tracking