OpenCV学习之椭圆曲线拟合
程序员文章站
2024-01-28 09:56:16
...
程序首先发现图像的轮廓,然后用椭圆逼近它。
//椭圆曲线拟合
#include "cv.h"
#include "highgui.h"
int slider_pos = 70;
IplImage *image02 = 0, *image03 = 0, *image04 = 0;
void process_image(int h);
int main(int argc, char** argv)
{
// 读入图像,强制为灰度图像
image03 = cvLoadImage("corner.tif", 0);
// Create the destination images
image02 = cvCloneImage(image03);
image04 = cvCloneImage(image03);
// Create windows.
cvNamedWindow("Source", 1);
cvNamedWindow("Result", 1);
// Show the image.
cvShowImage("Source", image03);
// Create toolbars. HighGUI use.
cvCreateTrackbar("Threshold", "Result", &slider_pos, 255, process_image);
process_image(0);
// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image02);
cvReleaseImage(&image03);
cvDestroyWindow("Source");
cvDestroyWindow("Result");
return 0;
}
// Define trackbar callback functon. This function find contours,
// draw it and approximate it by ellipses.
void process_image(int h)
{
CvMemStorage* stor;
CvSeq* cont;
CvBox2D32f* box;
CvPoint* PointArray;
CvPoint2D32f* PointArray2D32f;
// 创建动态结构序列
stor = cvCreateMemStorage(0);
cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), stor);
// 二值话图像.
cvThreshold(image03, image02, slider_pos, 255, CV_THRESH_BINARY);
// 寻找所有轮廓.
cvFindContours(image02, stor, &cont, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
// Clear images. IPL use.
cvZero(image02);
cvZero(image04);
// 本循环绘制所有轮廓并用椭圆拟合.
for (; cont; cont = cont->h_next)
{
int i; // Indicator of cycle.
int count = cont->total; // This is number point in contour
CvPoint center;
CvSize size;
// Number point must be more than or equal to 6 (for cvFitEllipse_32f).
if (count < 6)
continue;
// Alloc memory for contour point set.
PointArray = (CvPoint*)malloc(count * sizeof(CvPoint));
PointArray2D32f = (CvPoint2D32f*)malloc(count * sizeof(CvPoint2D32f));
// Alloc memory for ellipse data.
box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f));
// Get contour point set.
cvCvtSeqToArray(cont, PointArray, CV_WHOLE_SEQ);
// Convert CvPoint set to CvBox2D32f set.
for (i = 0; i<count; i++)
{
PointArray2D32f[i].x = (float)PointArray[i].x;
PointArray2D32f[i].y = (float)PointArray[i].y;
}
//拟合当前轮廓.
cvFitEllipse(PointArray2D32f, count, box);
// 绘制当前轮廓.
cvDrawContours(image04, cont, CV_RGB(255, 255, 255),
CV_RGB(255, 255, 255), 0, 1, 8, cvPoint(0, 0));
// Convert ellipse data from float to integer representation.
center.x = cvRound(box->center.x);
center.y = cvRound(box->center.y);
size.width = cvRound(box->size.width*0.5);
size.height = cvRound(box->size.height*0.5);
box->angle = -box->angle;
// Draw ellipse.
cvEllipse(image04, center, size,
box->angle, 0, 360,
CV_RGB(0, 0, 255), 1, CV_AA, 0);
// Free memory.
free(PointArray);
free(PointArray2D32f);
free(box);
}
// Show image. HighGUI use.
cvShowImage("Result", image04);
}
下一篇: 阅卷器的数字图像处理部分