《OpenCV》Part9 OpenCV3.1.0 拟合视频/相机获取的光斑
根据前几节介绍,做了一个拟合视频/相机中的激光光斑,算法部分还需要自己改进,这边用的还是椭圆拟合与直线划线定位圆心。
目前做的是灰度图像中的定位,直接在原始视频中的定位需要自己改。该代码可以定位晚上的激光光尖位置,可以通过CCD观测北极星位置,对激光器定位校准。
精度可以自己提高,光斑的位置还可以添加重心法来追踪拟合,光尖也可以使用三角形标注来识别光尖位置,也可以使用snake(主动轮廓模型)算法定位追踪,当然还有其他的好的方法,自己改。光斑位置定位在上篇博文中也有介绍,亚像素级,精度上还是可以的。
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int sliderPos = 70;
Mat image, img_src1;
void processImage(int, void*);
void drawLine(int, void*);
void huoghLineFind();
bool pause = false;
int main(int argc, char** argv)
{
VideoCapture capture(0);//"bike.avi"
//1//VID_20150617_205323.mp4
//2//VID_20151024_185222.mp4
//const char* filename = "fitline.jpg";//laser6.jpg//fitline.jpg
// image = imread(filename, 0);
//if (0 == image.isOpened())
//{
// cout << "Couldn't open Video or camera!\n";
// return 0;
//}
//Create two new windows to show frams
namedWindow("Foreground", 0);
namedWindow("TargetCapture", 1);
//Process each frame to capture targets
for (;;)
{
capture >> img_src1;
if (!pause)
{
waitKey(33);
if (capture.isOpened())//endpty
{
imshow("Foreground", img_src1);
}
else
{
return 0;
}
}
//// Create toolbars. HighGUI use.
createTrackbar("threshold", "TargetCapture", &sliderPos, 255);
//processImage(0, 0);
//drawLine(0, 0);
////////////////////////////////ProcessImage(int,void*)//////////////////////////////////////////
vector<vector<Point> > contours;
Mat gray = img_src1 >= sliderPos;
Mat bimage;
cvtColor(gray, bimage, CV_BGR2GRAY);
findContours(bimage, contours, RETR_LIST, CHAIN_APPROX_NONE);//RETR_LIST //RETR_FLOODFILL
Mat cimage = Mat::zeros(bimage.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); i++)
{
size_t count = contours[i].size();
if (count < 6)
continue;
Mat pointsf;
Mat(contours[i]).convertTo(pointsf, CV_32F);
RotatedRect box = fitEllipse(pointsf);
if (MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height) * 30)
continue;
drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8);
ellipse(cimage, box, Scalar(0, 0, 255), 1, LINE_AA);
ellipse(cimage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(0, 255, 255), 1, LINE_AA);
Point2f vtx[4];
box.points(vtx);
for (int j = 0; j < 4; j++)
line(cimage, vtx[j], vtx[(j + 1) % 4], Scalar(0, 255, 0), 1, LINE_AA);
}
if (!cimage.empty())
{
imshow("TargetCapture", cimage);//TargetCapture
}
else
{
exit(1);
}
////////////////////////////////DrawLine(int,void*)////////////////////////////////////////
//namedWindow("drawLine", 2);
//vector<vector<Point> > contours;
//Mat bimage = img_src1 >= sliderPos;
findContours(bimage, contours, RETR_LIST, CHAIN_APPROX_NONE);
//Mat cimage = Mat::zeros(bimage.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); i++)
{
size_t count = contours[i].size();
if (count < 6)
continue;
Mat pointsf;
Mat(contours[i]).convertTo(pointsf, CV_32F);
RotatedRect box = fitEllipse(pointsf);
if (MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height) * 30)
continue;
Point2f vtx[4];
box.points(vtx);
for (int j = 0; j < 4; j++)
//int j = 4;
line(cimage, (vtx[j] + vtx[(j + 3) % 4]) / 2, (vtx[(j + 1) % 4] + vtx[(j + 2) % 4]) / 2, Scalar(225, 10, 10), 1, LINE_AA);
}
if (!cimage.empty())
{
imshow("TargetCapture", cimage);//drawLine//TargetCapture
}
else
{
exit(1);
}
//////////////////////////////////////////////////////////////////////////
char key = cv::waitKey(50);
if (key == 33)
{
break;
}
if (key == ' ')
pause = !pause;
}
// Wait for a key stroke; the same function arranges events processing
waitKey();
return 0;
}
// Define trackbar callback functon. This function find contours,
// draw it and approximate it by ellipses.