使用CodeBlock+openCV完成本次Project,编译运行后的exe的链接附在博客后面,画圆时进行了一下拓展,使圆可以进行填充,使用的算法如下:
1. 画线算法:Bresenham算法
代码如下:
#include "cv.h"
#include "highgui.h"
#include <cmath>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
//初始化
CvSize window={500,500};//窗口大小
CvPoint p1;
CvPoint p2;
IplImage *img;
//dx>dy前提下的xVector>0和xVector<0两种情况
void draw1(CvPoint *p1, CvPoint *p2,int &xVector, int &yVector ,int &dx, int &dy){
int eps = 2*dy - dx;
int x;
int y = p1->y;
for(x = p1->x; (xVector > 0 ? x<= p2->x : x>=p2->x) ;x+=xVector){
//直线RGB(颜色)设置
img->imageData[y*img->widthStep + x*3+1] = (signed char)255;
img->imageData[y*img->widthStep + x*3+2] = (signed char)255;
if(xVector>0){
img->imageData[y*img->widthStep + x*3] = (signed char)255;//白色
}else{
img->imageData[y*img->widthStep + x*3] = (signed char)0;//黄色
}
if (eps>=0){
y += yVector;
eps += (2*dy-2*dx);
}
else{
eps += 2*dy;
}
}
}
//dy>dx前提下的yVector>0和yVector<0两种情况
void draw2(CvPoint *p1, CvPoint *p2,int &xVector, int &yVector ,int &dx, int &dy){
int eps = 2*dx - dy;
int x = p1->x;
int y;
for (y = p1->y; (yVector >=0 ? y<= p2->y : y>=p2->y) ;y+=yVector){
img->imageData[y*img->widthStep + x*3] = (signed char)0;
if(yVector>0){
img->imageData[y*img->widthStep + x*3+1] = (signed char)255;
img->imageData[y*img->widthStep + x*3+2] = (signed char)0;//绿色
}else{
img->imageData[y*img->widthStep + x*3+1] = (signed char)0;//红色
img->imageData[y*img->widthStep + x*3+2] = (signed char)255;
}
if (eps>=0){
x += xVector;
eps += (2*dx-2*dy);
}
else{
eps += 2*dx;
}
}
}
void drawLine(CvPoint *p1, CvPoint *p2){
//方向向量分别用于确定x,y轴的方向
int xVector;//x轴方向向量
int yVector;//y轴方向向量
int dx = abs(p1->x - p2->x);
int dy = abs(p1->y - p2->y);
cvSet (img, cvScalarAll (0), 0);
cvShowImage("window",img);
if (p1->x >= p2->x){//确定x轴方向向量
xVector = -1;
}else{
xVector = 1;
}
if (p1->y >= p2->y){//确定y轴方向向量
yVector = -1;
}else{
yVector = 1;
}
if (dx>=dy){
draw1(p1,p2,xVector,yVector,dx,dy);//|k|<=1
}
else{
draw2(p1,p2,xVector,yVector,dx,dy);//|k|>1
}
cvShowImage("window",img);
}
int main( int argc, char **argv){
img = cvCreateImage(window,IPL_DEPTH_8U,3);
cvSet (img, cvScalarAll (0), 0);
cout<<"Please enter the first point:"<<endl;
cin>>p1.x>>p1.y;
cout<<"p1("<<p1.x<<","<<p1.y<<")"<<endl;
cout<<"Please enter the second point:"<<endl;
cin>>p2.x>>p2.y;
cout<<"p2("<<p2.x<<","<<p2.y<<")"<<endl;
cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",img);
drawLine(&p1,&p2);
//cvSetMouseCallback("window", Mouse);
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow("window");
return 0;
}
运行结果:
起始坐标点:(100,100) - (400,400)
结果截图:
2. 画圆算法:Bresenham算法
代码如下:
#include <iostream>
#include "cv.h"
#include "highgui.h"
using namespace std;
CvSize window={500,500};//窗口大小
CvPoint p;
IplImage *img;
void drawPixel(int x, int y){
img->imageData[y*img->widthStep + x*3] = (signed char)0;
img->imageData[y*img->widthStep + x*3+1] = (signed char)255;
img->imageData[y*img->widthStep + x*3+2] = (signed char)255;
}
void drawSymmetry(CvPoint *p, int x, int y){//利用八对称性
drawPixel(p->x + x, p->y + y);
drawPixel(p->x - x, p->y + y);
drawPixel(p->x + x, p->y - y);
drawPixel(p->x - x, p->y - y);
drawPixel(p->x + y, p->y + x);
drawPixel(p->x + y, p->y - x);
drawPixel(p->x - y, p->y + x);
drawPixel(p->x - y, p->y - x);
}
void drawCircle(CvPoint *p, int x, int y, int d, int fill){
int a=0;
cvSet (img, cvScalarAll (0), 0);
cvShowImage("window",img);
if (fill) {
// 如果填充(画实心圆)
while (x <= y) {
for (a = x; a <= y; a ++){
drawSymmetry(p, x, a);
}
if (d < 0) {
d = d + 4 * x + 6;
} else {
d = d + 4 * (x - y) + 10;
y --;
}
x++;
}
cout<<"fill1 is:"<<fill<<endl;
}
else {
while(x <= y){
//RGB(颜色)设置
drawSymmetry(p, x, y);
if (d < 0) {
d = d + 4 * x + 6;
}
else {
d = d + 4 * (x - y) + 10;
y--;
}
x++;
}
cout<<"fill2 is:"<<fill<<endl;
}
drawPixel(p->x, p->y);//将原点画在面板上
cvShowImage("window",img);
}
int main()
{
img = cvCreateImage(window,IPL_DEPTH_8U,3);
cvSet (img, cvScalarAll (0), 0);
int r;
//初始化
cout<<"输入圆心坐标:"<<endl;
cin>>p.x>>p.y;
cout<<"圆心坐标为:("<<p.x<<","<<p.y<<")"<<endl;
cout<<"请输入半径:"<<endl;
cin>>r;
cout<<"半径为:"<<r<<endl;
int fill;
cout<<"请确定是否想填充圆(1-yes/0-no):"<<endl;
cin>>fill;
cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",img);
int x = 0, y = r;
int d = 3 - 2 * r;
drawCircle(&p, x, y, d, fill);
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow("window");
return 0;
}
运行结果:
圆心坐标:(200,200) 圆半径:100
未填充圆状态:
填充圆状态:
画线及画圆算法的exe文件:http://pan.baidu.com/s/1nt9gVGX