Opencv边缘检测

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

#include <iostream>


using namespace std;
using namespace cv;

#define PARASACLAR		10
#define SPLICINGNUM		4
#define VIDEOPATH	("./video/demo1.mp4")
#define IMAGEPATH	("./picture/bus.jpg")
#define CAMERAID	0

enum VIDEOMODE {
	E_CAMERA = 0,
	E_VIDEO,
};
void createParaWin()
{
	int thre1, thre2, area;
	thre1 = 155*PARASACLAR;
	thre2 = 255*PARASACLAR;
	area = 2000*PARASACLAR;
	namedWindow("para");
	resizeWindow("para", 640, 240);
	createTrackbar("Threshold1", "para", &thre1, 255 * PARASACLAR, NULL);
	createTrackbar("Threshold2", "para", &thre2, 255 * PARASACLAR, NULL);
	createTrackbar("Area", "para", &area, 30000 * PARASACLAR, NULL);
}

void getContours(Mat imgDil, Mat imgCon)
{
	vector<vector<Point>> contours;
	vector<Point> cnt, approx;
	vector<Vec4i> hierachy;
	String str;
	double peri;
	const cv::Scalar color(255, 0, 255);
	float areaMin=0.0f,area = 0.0f;

	cv::findContours(imgDil, contours, hierachy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
	cv::drawContours(imgCon, contours, -1, color);
	cv::Rect rect;
	areaMin =(float)cv::getTrackbarPos("Area", "para") / (float)PARASACLAR;
	for (int i = 0; i < contours.size(); i++)
	{
		cnt = contours[i];
		area = (float)contourArea( cnt );
		if (area - areaMin > 0.000001)
		{
			peri = cv::arcLength(cnt, true);
			cv::approxPolyDP(cnt, approx, peri*0.02, true);
			rect = boundingRect(approx);

			cv::rectangle(imgCon, rect, cv::Scalar(0, 255, 0), 2);
			//cout << "Lenght: " << approx.size() << endl;
			str = "Ponit";
			cv::putText(imgCon, str + to_string(approx.size()), 
						Point(rect.x + rect.width +20,rect.y+20), 
						cv::FONT_HERSHEY_COMPLEX, 0.4, cv::Scalar(0, 255, 0));
			str = "Area";
			cv::putText(imgCon, str + to_string(area),
				Point(rect.x + rect.width + 20, rect.y + 45),
				cv::FONT_HERSHEY_COMPLEX, 0.4, cv::Scalar(0, 255, 0));
			cv::line( imgCon,
					  Point(rect.x + rect.width/2-5, rect.y + rect.height/2),
					  Point(rect.x + rect.width/2+5, rect.y + rect.height/2),
					  Scalar(0, 255, 0));
			cv::line( imgCon, 
					  Point(rect.x + rect.width / 2, rect.y + rect.height / 2 - 5), 
					  Point(rect.x + rect.width / 2, rect.y + rect.height / 2 + 5), 
					  Scalar(0,255,0));
		}
	}
}

int twoView(Mat &m1, Mat&m2, Mat& dts)
{
	int dis = 5,nCol, nRow,type;
	type = m1.type();
	if ( type != m2.type())
	{
		cout << "type ne" << endl;
		return -1;
	}
	nCol = m1.cols;
	nRow = m1.rows;
	dts = Mat::zeros(cv::Size(nCol * 2 + dis, nRow), type);
	Rect roi(0, 0, nCol, nRow);
	m1.copyTo(dts(roi));
	roi.x = m1.cols + dis;
	m2.copyTo(dts(roi));
	return 0;
}

int loadVideo(VideoCapture &cap, VIDEOMODE mode)
{
	if (mode == E_CAMERA)
	{
		cap.open(CAMERAID, cv::CAP_ANY);
	}
	else if (mode = E_VIDEO)
	{
		cap.open(VIDEOPATH);
	}
	else
	{
		Mat img = imread(IMAGEPATH);
		if (img.empty())
		{
			cout << "图片文件不存在!" << endl;
			system("pause");
			return -2;
		}
		namedWindow("Hello World!");	//添加图片窗口名称
		imshow("Hello World!", img);	//显示图片
		waitKey(0);						//系统暂停,等待键盘事件
		destroyWindow("Hello World!");	//销毁窗口
		cout << "ERROR: Unable open camera!\n" << endl;
	}
	if (!cap.isOpened()) {
		cout << "ERROR: Unable open VideoCamare ....\n" << endl;
		cap.release();
		return -1;
	}
	cap.set(3, 480);
	cap.set(4, 240);
	return 0;
}

int main()
{
	Size kernel;
	Mat frame, frContour, imgBlur,imgGray, imgCanny, imgDilate, element;
	vector<Mat> splicVec;
	VideoCapture cap;
	float thre1, thre2;
	//1.初始化参数
	kernel.width = 7;
	kernel.height = 7;
	element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));

	//2.获取视频帧/图像
	if (loadVideo(cap, E_CAMERA) < 0) {
		return -1;
	}

	//3.创建追踪参数窗口
	createParaWin();
	
	for (;;) {
		//1.逐帧读取,copy轮廓图像
		cap.read(frame);
		if (frame.empty())
		{
			cout << "ERROR: blank frame grabbed\n" << endl;
			break;
		}
		frame.copyTo(frContour);
		//2.图像高斯模糊,转为灰度图
		cv::GaussianBlur(frame, imgBlur, kernel, 1);
		cv::cvtColor(imgBlur, imgGray, cv::COLOR_BGR2GRAY);

		//3.Canny边缘检测灰度图
		thre1 = (float)cv::getTrackbarPos("Threshold1", "para") / (float)PARASACLAR;
		thre2 = (float)cv::getTrackbarPos("Threshold2", "para") / (float)PARASACLAR;
		cv::Canny(imgGray, imgCanny, thre1, thre2);
		
		//4.膨胀Canny边缘图像
		cv::dilate(imgCanny, imgDilate, element);
		
		//5.处理轮廓图像
		getContours(imgDilate, frContour);		
#if 0
		cout<<"blur type"<<imgBlur.type()<<endl;
		cout<<"gray type"<<imgGray.type()<<endl;
		cout << "canny" << imgCanny.type() << endl;
		cout << "dilate type" << imgDilate.type() << endl;
#endif
		Mat dts;
		twoView(frame,frContour,dts);
		cv::imshow("type16", dts);
		twoView(imgCanny, imgDilate, dts);
		cv::imshow("type0", dts);
		if (waitKey(5) == 'q') {
			destroyAllWindows();//销毁窗口
			break;
		}
			
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ai_Sj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值