《OpenCV》Part6 OpenCV3.1.0 用直线拟合图像中的物体
2016-11-21 13:21
363 查看
《OpenCV》Part6 OpenCV3.1.0 用直线拟合图像中的物体
1、先来用几个点来拟合出直线,
示例1:
2、用椭圆拟合图片中物体
fitellipse.cpp:/********************************************************************************
*
*
* This program is demonstration for ellipse fitting. Program finds
* contours and approximate it by ellipses.
*
* Trackbar specify threshold parametr.
*
* White lines is contours. Red lines is fitting ellipses.
*
*
********************************************************************************/
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
// static void help()
// {
// cout <<
// "\nThis program is demonstration for ellipse fitting. The program finds\n"
// "contours and approximate it by ellipses.\n"
// "Call:\n"
// "./fitellipse [image_name -- Default ../data/fitline.jpg]\n" << endl;
// }
int sliderPos = 70;
Mat image;
void processImage(int, void*);
void drawLine(int, void*);
void huoghLineFind();
int main(int argc, char** argv)
{
//const char* filename = argc == 2 ? argv[1] : (char*)"../data/fitline.jpg";
const char* filename = "fitline.jpg";//laser6.jpg//fitline.jpg
image = imread(filename, 0);
if (image.empty())
{
cout << "Couldn't open image " << filename << "\nUsage: fitellipse <image_name>\n";
return 0;
}
imshow("source", image);
namedWindow("result", 1);
// Create toolbars. HighGUI use.
createTrackbar("threshold", "result", &sliderPos, 255, processImage);
processImage(0, 0);
drawLine(0, 0);
// 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.
void processImage(int /*h*/, void*)
{
vector<vector<Point> > contours;
Mat bimage = image >= 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;
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);
}
imshow("result", cimage);
}
void drawLine(int, void*)
{
namedWindow("drawLine", 2);
vector<vector<Point> > contours;
Mat bimage = image >= 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;
//int row = cimage.cols;
//int col = cimage.rows;
//float line[4]; //输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0)
//其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点
//Point2f vtx[4];
//box.points(vtx);
//Mat pointMat = Mat(1, count, CV_32SC2, vtx); //点集, 存储count个随机点points
//cvFitLine(&pointMat, DIST_L1, 1, 0.001, 0.001,line);
//int lefty = int((-x*vy / vx) + y);
//int righty = int(((cols - x)*vy / vx) + y);
//box结构中包含椭圆的中心坐标, 将椭圆数据从浮点转化为整数表示
//Point x = cvRound(box.center.x);
//Point y = cvRound(box.center.y);
//line(cimage,Point(0,0),(x,y),Scalar(255,255,0),2,LINE_AA);
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);
}
imshow("drawLine", cimage);
}
1、先来用几个点来拟合出直线,
示例1:
#include "cv.h" #include "highgui.h" #include <math.h> int main(int argc, char* argv[]) { IplImage* img = cvCreateImage(cvSize(500, 500), 8, 3); CvRNG rng = cvRNG(-1); //cvRNG()跟一般的C语言srand()使用方法一样,要先给它一个种子, //但srand()用到的是unsigned int的32位种子范围,而cvRNG()用的是64位长整数种子。 //初始化CvRNG资料结构,假如seed给0,它将会自动转成-1 cvRNG(64位种子) cvNamedWindow("fitline", 1); for (;;) { char key; int i; int count = cvRandInt(&rng) % 100 + 1; //产生1-100 之间的数 int outliers = count / 5; // 奇异点的个数。0--20 之间的数 printf("count = %d", count); float a = cvRandReal(&rng) * 200; // 0~ 199 之间的浮点数 [cvRandReal 浮点型随机数并更新 RNG ,范围在 0..1 之间,不包括 。 float b = cvRandReal(&rng) * 40; //返回0 ~ 39之间的数 float angle = cvRandReal(&rng)*CV_PI; printf("count = %f", angle); float cos_a = cos(angle), sin_a = sin(angle); printf("cos_a = %f", cos_a); CvPoint pt1, pt2; //直线的两个端点 CvPoint* points = (CvPoint*)malloc(count * sizeof(points[0])); //存放随机产生的点点,数目为count CvMat pointMat = cvMat(1, count, CV_32SC2, points); //点集, 存储count个随机点points float line[4]; //输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0) //其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点 float d, t; b = MIN(a*0.3, b); // generate some points that are close to the line for (i = 0; i < count - outliers; i++) { float x = (cvRandReal(&rng) * 2 - 1)*a; float y = (cvRandReal(&rng) * 2 - 1)*b; points[i].x = cvRound(x*cos_a - y*sin_a + img->width / 2); points[i].y = cvRound(x*sin_a + y*cos_a + img->height / 2); } // generate "completely off" points for (; i < count; i++) { points[i].x = cvRandInt(&rng) % img->width; points[i].y = cvRandInt(&rng) % img->height; } // find the optimal line 曲线拟合 cvFitLine(&pointMat, CV_DIST_L1, 1, 0.001, 0.001, line); cvZero(img); //画出产生的随机分布的点点 for (i = 0; i < count; i++) cvCircle(img, points[i], 2, i < count - outliers ? CV_RGB(255, 0, 0) : CV_RGB(255, 255, 0), CV_FILLED, CV_AA, 0); // ... and the long enough line to cross the whole image d = sqrt((double)line[0] * line[0] + (double)line[1] * line[1]); //line[0 & 1]存储的是单位向量,所以d=1 //printf("\n %f\n", d); line[0] /= d; line[1] /= d; //画出线段的两个端点(避免线太短,以线上一个随机点向两侧延伸line[0]*t ) t = (float)(img->width + img->height); pt1.x = cvRound(line[2] - line[0] * t); pt1.y = cvRound(line[3] - line[1] * t); pt2.x = cvRound(line[2] + line[0] * t); pt2.y = cvRound(line[3] + line[1] * t); cvLine(img, pt1, pt2, CV_RGB(0, 255, 0), 3, CV_AA, 0); cvShowImage("fitline", img); key = (char)cvWaitKey(0); if (key == 27 || key == 'q' || key == 'Q') // 'ESC' break; free(points); } cvDestroyWindow("fitline"); return 0; }
2、用椭圆拟合图片中物体
fitellipse.cpp:/********************************************************************************
*
*
* This program is demonstration for ellipse fitting. Program finds
* contours and approximate it by ellipses.
*
* Trackbar specify threshold parametr.
*
* White lines is contours. Red lines is fitting ellipses.
*
*
********************************************************************************/
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
// static void help()
// {
// cout <<
// "\nThis program is demonstration for ellipse fitting. The program finds\n"
// "contours and approximate it by ellipses.\n"
// "Call:\n"
// "./fitellipse [image_name -- Default ../data/fitline.jpg]\n" << endl;
// }
int sliderPos = 70;
Mat image;
void processImage(int, void*);
void drawLine(int, void*);
void huoghLineFind();
int main(int argc, char** argv)
{
//const char* filename = argc == 2 ? argv[1] : (char*)"../data/fitline.jpg";
const char* filename = "fitline.jpg";//laser6.jpg//fitline.jpg
image = imread(filename, 0);
if (image.empty())
{
cout << "Couldn't open image " << filename << "\nUsage: fitellipse <image_name>\n";
return 0;
}
imshow("source", image);
namedWindow("result", 1);
// Create toolbars. HighGUI use.
createTrackbar("threshold", "result", &sliderPos, 255, processImage);
processImage(0, 0);
drawLine(0, 0);
// 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.
void processImage(int /*h*/, void*)
{
vector<vector<Point> > contours;
Mat bimage = image >= 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;
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);
}
imshow("result", cimage);
}
void drawLine(int, void*)
{
namedWindow("drawLine", 2);
vector<vector<Point> > contours;
Mat bimage = image >= 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;
//int row = cimage.cols;
//int col = cimage.rows;
//float line[4]; //输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0)
//其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点
//Point2f vtx[4];
//box.points(vtx);
//Mat pointMat = Mat(1, count, CV_32SC2, vtx); //点集, 存储count个随机点points
//cvFitLine(&pointMat, DIST_L1, 1, 0.001, 0.001,line);
//int lefty = int((-x*vy / vx) + y);
//int righty = int(((cols - x)*vy / vx) + y);
//box结构中包含椭圆的中心坐标, 将椭圆数据从浮点转化为整数表示
//Point x = cvRound(box.center.x);
//Point y = cvRound(box.center.y);
//line(cimage,Point(0,0),(x,y),Scalar(255,255,0),2,LINE_AA);
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);
}
imshow("drawLine", cimage);
}
相关文章推荐
- 曲线拟合的最小二乘法(基于OpenCV实现)的,拟合图像中离散点的拟合直线
- 《OpenCV》Part9 OpenCV3.1.0 拟合视频/相机获取的光斑
- 基于OpenCV的图像直线分析和拟合工具
- opencv之7.4用直线拟合一组点
- 算法+OpenCV】基于opencv的直线和曲线拟合与绘制(最小二乘法)
- OPENCV霍夫变换使用方法——边缘检测+霍夫变换求出图像中的直线
- 图像处理中拟合直线的几种方法
- 学习opencv,使用反向块投影搜索图像中物体的位置cvCalcBackProjectPatch
- opencv拟合直线并在屏幕上绘出
- 【图像处理】openCV光流法追踪运动物体
- Python3与OpenCV3.3 图像处理(十九)--直线检测
- OpenCV 学习(直线拟合)
- 【OpenCV3图像处理】绘图功能总结(直线,矩形,圆,椭圆,多边形,文字)
- 学习opencv 使用反向块投影搜寻图像中的物体的位置 cvCalcBackProjectPatch
- matlab使用opencv (轮廓提取+直线拟合)
- OpenCV实现图像物体轮廓,前景背景,标记,并保存。
- opencv笔记:检测轮廓,直线,圆以及直线拟合
- OpenCV2马拉松第25圈——直线拟合与RANSAC算法
- 《OpenCV》Part8 OpenCV3.1.0 图像相加与曝光
- 图像处理中的椭圆拟合(opencv)之看的论文的意思的代码