opencv练习

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

//#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/features2d/features2d.hpp>
//#include <opencv2/legacy/legacy.hpp>

#include <iostream>
using namespace std;
using namespace cv;

cv:: Mat img;
int Threhold = 160;

int ErodeOrDilateNum = 0;
int StructElementSize = 3;

Mat srcImage, dstImage;

void process();
void on_ErodeOrDilateChange(int, void*);
void on_StructElementSizeChange(int, void*);

vector<Point> vecPoint;
vector<vector<Point>> vec2Point;

Point stPoint(-1, -1);
Point curPoint(-1, -1);




void on_mouse(int event, int x, int y, int flags, void *ustc);


static void on_trackbar(int, void*)
{
	Mat bw = (Threhold < 128) ? (img < Threhold) : (img > Threhold); 

	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;

	findContours( bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

	//初始化dst
	Mat dst = Mat::zeros(img.size(), CV_8UC3);
	//开始处理
	if( !contours.empty() && !hierarchy.empty() )
	{
		//遍历所有顶层轮廓,随机生成颜色值绘制给各连接组成部分
		int idx = 0;
		for( ; idx >= 0; idx = hierarchy[idx][0] )
		{
			Scalar color( (rand()&255), (rand()&255), (rand()&255) );
			//绘制填充轮廓
			drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy );
		}
	}
	//显示窗口
	imshow( "TrackImage", dst );


}

int main()
{
	// 1.滑动条 和 contours
	/*img = cv::imread("./open_test.jpg", 0);

	if(!img.data)
	{
		cout<< "Open image failed!"<<endl;

		return -1;
	}

	namedWindow("Image", 1);
	imshow("Image", img);

	namedWindow("TrackImage", 1);

	createTrackbar("Trackbar", "TrackImage", &Threhold, 255, on_trackbar);
	on_trackbar(Threhold, 0);*/



	// 2. Canny 边缘检测
	/*srcImage = cv::imread("./open_test.jpg", 1);

	Mat src_cp = srcImage.clone();

	if(!srcImage.data)
	{
		cout<< "Open image failed!"<<endl;

		return -1;
	}


	Mat gray, edge, dst;

	dst.create(src_cp.size(), src_cp.type());

	
	cvtColor(srcImage, gray, CV_BGR2GRAY);

	blur(gray, edge, Size(3, 3));

	Canny(edge, edge, 3, 9, 3);

	dst = Scalar::all(0);

	src_cp.copyTo(dst, edge);

	imshow("【效果图】Canny边缘检测", dst); */



	// 3.erode and dilate
    /*srcImage = cv::imread("./open_test.jpg", 1);

	Mat src_cp = srcImage.clone();

	if(!srcImage.data)
	{
		cout<< "Open image failed!"<<endl;

		return -1;
	}

	namedWindow("ErodeOrDilate", 1);

	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(2*StructElementSize+1,2*StructElementSize+1), Point(StructElementSize, StructElementSize));
	erode(srcImage, dstImage, element);

	imshow("ErodeOrDilate", dstImage);	

    //createTrackbar param: 1. 滑动条的名称  2. 依附窗口的名称  3. 当前滑动条位置  4. 总的位置大小  5. 回调函数, 只要滑动条位置改变,就会自动触发回调函数
    createTrackbar("ErodeOrDilateChange", "ErodeOrDilate", &ErodeOrDilateNum, 1, on_ErodeOrDilateChange);

	//on_ErodeOrDilateChange(ErodeOrDilateNum, 0);

	createTrackbar("StructElementSizeChange", "ErodeOrDilate", &StructElementSize, 21, on_StructElementSizeChange);

	//on_StructElementSizeChange(StructElementSize, 0);*/



	//4. Hough Transform
	/*srcImage = cv::imread("./open_test.jpg", 1);

	Mat midImage;

	if(!srcImage.data)
	{
		cout<< "Open image failed!"<<endl;

		return -1;
	}

	namedWindow("srcImage", 1);
	imshow("srcImage", srcImage);

	namedWindow("HoughImage", 1);

	Canny(srcImage, midImage, 3, 9, 3);

	cvtColor(midImage, dstImage, CV_GRAY2BGR);

	vector<Vec4i> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合
	HoughLinesP(midImage, lines, 1, CV_PI/180, 80, 50, 10 );

	for(int i = 0; i < lines.size(); i++)
	{
		line(dstImage, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(186, 88, 256), 1, CV_AA);
	}

	imshow("GrayImage", midImage);

	imshow("HoughImage", dstImage);*/


	// SURF     nonfree.hpp
	/*srcImage = cv::imread("./open_test.jpg", 1);
	Mat srcImage2 = cv::imread("./open_test2.jpg", 1);

	if(!srcImage.data || !srcImage2.data)
	{
		cout<< "Open image failed!"<<endl;

		return -1;
	}

	//【2】使用SURF算子检测关键点
	int minHassia = 700;
	SurfFeatureDetector detector(minHassia);

	vector<KeyPoint> keyPoint1, keyPoint2;

	detector.detect(srcImage, keyPoint1);
	detector.detect(srcImage2, keyPoint2);

	//【4】计算描述符(特征向量)
	SurfDescriptorExtractor extractor;
	Mat descriptor1, descriptor2;

	extractor.compute(srcImage, keyPoint1, descriptor1);
	extractor.compute(srcImage2, keyPoint2, descriptor2);

	//【5】使用BruteForce进行匹配
	// 实例化一个匹配器
	BruteForceMatcher< L2<float> > matcher;
	std::vector< DMatch > matches;

	matcher.match(descriptor1, descriptor2, matches);

	//【6】绘制从两个图像中匹配出的关键点
	Mat imgMatches;

	drawMatches(srcImage, keyPoint1, srcImage2, keyPoint2, matches, imgMatches);

	imshow("SURFImage", imgMatches);*/	


    //void polylines(Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed, const Scalar& color, int thickness=1, int lineType=8, int shift=0 );		
	// img:在img表示的图像上绘制
 //    pts:是指向多边形数组的指针,必须是const修饰的
 //    npts:是多边形顶点个数的数组名
 //    ncontours:绘制多边形的个数
	// isClosed:表示多边形是否闭合,1表示闭合,0表示不闭合
	// color:是填充的颜色


	srcImage = cv::imread("./open_test.jpg", 1);


	if(!srcImage.data)
	{
		cout<< "Open image failed!"<<endl;

		return -1;
	}

	namedWindow("srcImage", 1);

	setMouseCallback("srcImage", on_mouse, 0);  // 只要鼠标点击,就会自动调用

	cout<<"enter q to exit!"<<endl;
	while(char(waitKey(0))!='q')
	{

	}

	return 0;
}

// event
// CV_EVENT_MOUSEMOVE   =0,  //鼠标移动
// CV_EVENT_LBUTTONDOWN  =1,  //按下左键
// CV_EVENT_RBUTTONDOWN  =2,  //按下右键
// CV_EVENT_MBUTTONDOWN  =3,  //按下中键
// CV_EVENT_LBUTTONUP   =4,  //放开左键
// CV_EVENT_RBUTTONUP   =5,  //放开右键
// CV_EVENT_MBUTTONUP   =6,  //放开中键
// CV_EVENT_LBUTTONDBLCLK =7,  //左键双击
// CV_EVENT_RBUTTONDBLCLK =8,  //右键双击
// CV_EVENT_MBUTTONDBLCLK =9,  //中键双击
// CV_EVENT_MOUSEWHEEL   =10, //滚轮滚动
// CV_EVENT_MOUSEHWHEEL  =11  //横向滚轮滚动

// flags
// CV_EVENT_FLAG_LBUTTON  =1,  //左键拖拽
// CV_EVENT_FLAG_RBUTTON  =2,  //右键拖拽
// CV_EVENT_FLAG_MBUTTON  =4,  //中键拖拽
// CV_EVENT_FLAG_CTRLKEY  =8,  //按住CTRL拖拽
// CV_EVENT_FLAG_SHIFTKEY =16, //按住Shift拖拽
// CV_EVENT_FLAG_ALTKEY  =32  //按住ALT拖拽

// 原型 void putText( Mat& img, const string& text, Point org, int fontFace,double fontScale,  Scalar color, int thickness=1, int lineType=8 );
// 参数1:, Mat& img,待写字的图片,我们写在img图上

// 参数2:,const string& text,待写入的字,我们下面写入Hello

// 参数3:, Point org, 第一个字符左下角坐标,我们设定在图片的Point(50,60)坐标。表示x = 50,y = 60。

// 参数4:,int fontFace,字体类型,FONT_HERSHEY_SIMPLEX ,FONT_HERSHEY_PLAIN ,FONT_HERSHEY_DUPLEX 等等等。

// 参数5:,double fontScale,字体大小,我们设置为2号

// 参数6:,Scalar color,字体颜色,颜色用Scalar()表示,不懂得去百度。

// 参数7:, int thickness,字体粗细,我们下面代码使用的是4号

// 参数8:, int lineType,线型,我们使用默认值8.

//首先使用鼠标点击事件,鼠标点击事件的函数为:
void on_mouse(int event, int x, int y, int flags, void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号 
{
	if(event == CV_EVENT_LBUTTONDOWN)
	{
		stPoint = Point(x, y);

		vecPoint.push_back(stPoint);

		circle(srcImage, stPoint, 1, cv::Scalar(255, 0, 255), CV_FILLED, CV_AA, 0);

		imshow("srcImage", srcImage);

	}else if(event == CV_EVENT_MOUSEMOVE)// && (flags & CV_EVENT_FLAG_LBUTTON))
	{
		curPoint = Point(x, y);

		stringstream ss;

		ss << "x = " << curPoint.x << " y = " << curPoint.y;

		putText(srcImage,ss.str(),Point(50, 50),FONT_HERSHEY_SIMPLEX,2,Scalar(0,0,255),4,8); 

		ss.clear();



		/*line(srcImage,vecPoint.back(), curPoint, Scalar(255, 255, 255), 1, 8, 0);
		circle(srcImage, curPoint, 1, cv::Scalar(255, 0, 255), CV_FILLED, CV_AA, 0);

		vecPoint.push_back(curPoint);*/

		imshow("srcImage", srcImage);

	}else if(event == CV_EVENT_RBUTTONDOWN)
	{
		if(vecPoint.size() <=1)
		{
			vecPoint.clear();
			return;
		}

		vec2Point.push_back(vecPoint);
		/*for(auto i : vec2Point)
			for(auto j : i)
			{
				line(srcImage, j, )
			}*/

		for(int i = 0; i < vec2Point.size(); i++)
			for(int j = 1; j < vec2Point[i].size(); j++)
			{
				line(srcImage, vec2Point[i][j-1], vec2Point[i][j], Scalar(255, 255, 255), 1, 8, 0);
			}
		imshow("srcImage", srcImage);

		cout<<"vec2Point size = " << vec2Point.size() <<endl;

		vecPoint.clear();
	}else if(event == CV_EVENT_MBUTTONDOWN)
	{
		if(vecPoint.size() > 0)
		{
			vecPoint.pop_back();
			cout<< "vecPoint size = " << vecPoint.size()<<endl;

		}
		

		imshow("srcImage", srcImage);
	}

}

void on_ErodeOrDilateChange(int, void*)
{
	process();
}

void on_StructElementSizeChange(int, void*)
{
	process();
}

void process()
{
	Mat element = getStructuringElement(MORPH_RECT, Size(2*StructElementSize+1,2*StructElementSize+1), Point(StructElementSize, StructElementSize));

	if(ErodeOrDilateNum == 0)
	{
		erode(srcImage, dstImage, element);
	}
	else
	{
		dilate(srcImage,dstImage, element);
	}

	imshow("ErodeOrDilate", dstImage);


}

参考文献:
毛星云opencv专栏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值