#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;
}
Opencv边缘检测
于 2022-12-18 21:36:27 首次发布