5 c++ opencv feature-detection
我正在进行小型图像处理任务,我需要跟踪4个红色对象.我有如何跟踪单一的.我想知道跟踪多个点的最佳方法是什么.
有4个点定位形成一个矩形,所以我可以使用形状检测或角点检测来检测和跟踪点请参见下图.

以下是我在GitHub上的实现:https://github.com/Smorodov/Multitarget-tracker video on youube:http://www.youtube.com/watch?v = 2fW5TmAtAXM & list = UUhlR5ON5Uqhi_3RXRu-pdVw
简而言之:
顺便说一句,要获得4个点的坐标,你需要知道3个点的坐标,因为你的模式是矩形的,你可以计算出第4个点.
我的简单实现使用OpenCV 边界框中描述的技术来跟踪红色斑点。
以下是用于检索检测到的所有红色对象的中心的辅助函数:
/* get_positions: a function to retrieve the center of the detected blobs.
* largely based on OpenCV's "Creating Bounding boxes and circles for contours" tutorial.
*/
std::vector<cv::Point2f> get_positions(cv::Mat& image)
{
if (image.channels() > 1)
{
std::cout << "get_positions: !!! Input image must have a single channel" << std::endl;
return std::vector<cv::Point2f>();
}
std::vector<std::vector<cv::Point> > contours;
cv::findContours(image, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);
// Approximate contours to polygons and then get the center of the objects
std::vector<std::vector<cv::Point> > contours_poly(contours.size());
std::vector<cv::Point2f> center(contours.size());
std::vector<float> radius(contours.size());
for (unsigned int i = 0; i < contours.size(); i++ )
{
cv::approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 5, true );
cv::minEnclosingCircle((cv::Mat)contours_poly[i], center[i], radius[i]);
}
return center;
}
Run Code Online (Sandbox Code Playgroud)
我编写了代码,通过从网络摄像头捕获帧来实时测试我的方法。整个过程与@Dennis 描述的非常相似(抱歉,当你提交答案时我已经在编码了)。
好的,这就是乐趣真正开始的地方。
int main()
{
// Open the capture device. My webcam ID is 0:
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
std::cout << "!!! Failed to open webcam" << std::endl;
return -1;
}
// Let's create a few window titles for debugging purposes
std::string wnd1 = "Input", wnd2 = "Red Objs", wnd3 = "Output";
// These are the HSV values used later to isolate RED-ish colors
int low_h = 160, low_s = 140, low_v = 50;
int high_h = 179, high_s = 255, high_v = 255;
cv::Mat frame, hsv_frame, red_objs;
while (true)
{
// Retrieve a new frame from the camera
if (!cap.read(frame))
break;
cv::Mat orig_frame = frame.clone();
cv::imshow(wnd1, orig_frame);
Run Code Online (Sandbox Code Playgroud)
orig_frame:

// Convert BGR frame to HSV to be easier to separate the colors
cv::cvtColor(frame, hsv_frame, CV_BGR2HSV);
// Isolate red colored objects and save them in a binary image
cv::inRange(hsv_frame,
cv::Scalar(low_h, low_s, low_v),
cv::Scalar(high_h, high_s, high_v),
red_objs);
// Remove really small objects (mostly noises)
cv::erode(red_objs, red_objs, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
cv::dilate(red_objs, red_objs, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7)));
cv::Mat objs = red_objs.clone();
cv::imshow(wnd2, objs);
Run Code Online (Sandbox Code Playgroud)
objs:

// Retrieve a vector of points with the (x,y) location of the objects
std::vector<cv::Point2f> points = get_positions(objs);
// Draw a small green circle at those locations for educational purposes
for (unsigned int i = 0; i < points.size(); i++)
cv::circle(frame, points[i], 3, cv::Scalar(0, 255, 0), -1, 8, 0);
cv::imshow(wnd3, frame);
Run Code Online (Sandbox Code Playgroud)

char key = cv::waitKey(33);
if (key == 27) { /* ESC was pressed */
//cv::imwrite("out1.png", orig_frame);
//cv::imwrite("out2.png", red_objs);
//cv::imwrite("out3.png", frame);
break;
}
}
cap.release();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3540 次 |
| 最近记录: |