Open imuncle opened 4 years ago
要实现嵌入式视觉开发,首先得把最强大最经典的OpenCV学会。
我参考的是毛星云主编的《OpenCV3编程入门》,过了一遍,记录了我比较关注的内容。学习时编写的源码如下:
#include <opencv2/opencv.hpp> using namespace cv; using namespace std; const int g_nMaxAlphaValue = 100; //Alpha值的最大值 int g_nAlphaValueSlider; //滑动条对应的变量 double g_dAlphaValue; double g_bBetaValue; Mat g_srcImage1; Mat g_srcImage2; Mat g_srcImage; Rect g_rectangle; bool g_bDrawingBox = false; //是否进行绘制 RNG g_rng(12345); int g_nContrastValue; //对比度 int g_nBrightValue; //亮度值 Mat src_Image, dstImage; //响应滑动条的回调函数 void on_Trackbar(int , void*) { g_dAlphaValue = (double)g_nAlphaValueSlider/g_nMaxAlphaValue;//求出当前你alpha值相对于最大值的比值 g_bBetaValue = 1.0 - g_dAlphaValue; addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_bBetaValue, 0.0, g_srcImage); imshow("【滑动条】图像混合",g_srcImage); } //自定义的矩形绘制函数 void DrawRectangle(cv::Mat& img, cv::Rect box) { rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0,255), g_rng.uniform(0,255), g_rng.uniform(0,255)));//随机颜色 } //鼠标回调函数,根据不同的鼠标事件进行不同的鼠标操作 void on_MouseHandle(int event, int x, int y, int flags, void* param) { Mat &image = *(cv::Mat*) param; switch(event) { //鼠标移动消息 case EVENT_MOUSEMOVE: { if(g_bDrawingBox) { g_rectangle.width = x - g_rectangle.x; g_rectangle.height = y - g_rectangle.y; } } break; //左键按下消息 case EVENT_LBUTTONDOWN: { g_bDrawingBox = true; g_rectangle = Rect(x,y,0,0); } break; //左键抬起消息 case EVENT_LBUTTONUP: { g_bDrawingBox = false; if(g_rectangle.width < 0) { g_rectangle.x += g_rectangle.width; g_rectangle.width *= -1; } if(g_rectangle.height < 0) { g_rectangle.y += g_rectangle.height; g_rectangle.height *= -1; } DrawRectangle(image, g_rectangle); } } } //该表图像对比度和亮度值的回调函数 void on_ContrastAndBright(int, void *) { for(int y=0; y<src_Image.rows;y++) { for(int x=0;x<src_Image.cols;x++) { for(int c=0;c<3;c++) { dstImage.at<Vec3b>(y,x)[c] = saturate_cast<uchar>((g_nContrastValue*0.01)*(src_Image.at<Vec3b>(y,x)[c]) + g_nBrightValue); } } } imshow("【亮度对比度】", dstImage); } int main() { Mat img = imread("../test.jpeg"); Mat out; // boxFilter(img, out, -1, Size(5,5)); // imshow("【均值滤波】",out); // GaussianBlur(img, out, Size(3,3), 0, 0); // imshow("【高斯滤波】", out); //imshow("【原图】腐蚀操作",img); //显示图像 // medianBlur(img, out, 7); // imshow("【中值滤波】", out); // bilateralFilter(img, out, 2, 25*2, 25/2); // imshow("【双边滤波】",out); Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));//获取自定义内核 // dilate(img, out, element);//膨胀 // imshow("【膨胀操作】", out); // erode(img, out, element); // imshow("【腐蚀操作】", out); // morphologyEx(img, out, MORPH_ERODE, element); // imshow("【腐蚀操作】", out); // morphologyEx(img, out, MORPH_DILATE, element); // imshow("【膨胀操作】", out); // morphologyEx(img, out, MORPH_OPEN, element); // imshow("【开运算】", out); // morphologyEx(img, out, MORPH_CLOSE, element); // imshow("【闭运算】", out); // morphologyEx(img, out, MORPH_GRADIENT, element); // imshow("【形态学梯度】", out); // morphologyEx(img, out, MORPH_TOPHAT, element); // imshow("【顶帽】", out); // morphologyEx(img, out, MORPH_BLACKHAT, element); // imshow("【黑帽】", out); Mat grad_x, grad_y; Mat abs_grad_x, abs_grad_y, dst; Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT); convertScaleAbs(grad_x, abs_grad_x); imshow("【效果图】x方向Sobel", abs_grad_x); Sobel(img, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT); convertScaleAbs(grad_y, abs_grad_y); imshow("【效果图】y方向Sobel", abs_grad_y); addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst); imshow("【效果图】整体方向SObel", dst); // Mat src_gray; // cvtColor(img, src_gray, COLOR_BGR2GRAY); // Laplacian(src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT); // convertScaleAbs(dst, src_gray); // imshow("【拉普拉斯变换】", src_gray); // Scharr(img, grad_x, CV_16S, 1,0, 1, 0,BORDER_DEFAULT); // convertScaleAbs(grad_x, abs_grad_x); // Scharr(img, grad_y, CV_16S, 0,1, 1, 0,BORDER_DEFAULT); // convertScaleAbs(grad_y, abs_grad_y); // addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst); // imshow("【Scharr滤波】", dst); Mat midImage; // Canny(img, midImage, 50, 200, 3); // cvtColor(midImage, dst, CV_GRAY2BGR); // vector<Vec2f> lines; // HoughLines(midImage, lines, 1, CV_PI/180, 150, 0, 0);//霍夫变换找直线 // for(size_t i=0;i<lines.size();i++) // { // float rho = lines[i][0], theta = lines[i][1]; // Point pt1, pt2; // double a = cos(theta), b = sin(theta); // double x0 = a*rho, y0 = b*rho; // pt1.x = cvRound(x0 + 1000*(-b)); // pt1.y = cvRound(y0 + 1000*(a)); // pt2.x = cvRound(x0 - 1000*(-b)); // pt2.y = cvRound(y0 - 1000*(a)); // line(img, pt1, pt2, Scalar(55,100,195), 1, LINE_AA); // } // imshow("【霍夫变换】寻找直线", img); // cvtColor(img, midImage, COLOR_BGR2GRAY); // GaussianBlur(midImage, midImage, Size(9,9), 2, 2); // vector<Vec3f> circles; // HoughCircles(midImage, circles, HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0);//霍夫变换寻找圆圈 // for(size_t i = 0;i<circles.size();i++) // { // Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); // int radius = cvRound(circles[i][2]); // circle(img, center, 3, Scalar(0,255,0), -1, 8, 0); // circle(img, center, radius, Scalar(155,50,255),3,8,0); // } // imshow("【霍夫变换】寻找圆圈", img); // cvtColor(img, img, COLOR_BGR2GRAY); // imshow("【原始图】", img); // equalizeHist(img, dst); // imshow("【直方图均衡化】", dst); // img = imread("../test1.jpeg", 0); // imshow("原始图", img); // dst = Mat::zeros(img.rows, img.cols, CV_8UC3); // img = img > 119; // imshow("【取阈值后】", img); // vector<vector<Point>> contours; // vector<Vec4i> hierarchy; // findContours(img, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE); // int index = 0; // for(; index>=0;index = hierarchy[index][0]) // { // Scalar color(rand()&255, rand()&255, rand()&255); // drawContours(dst, contours, index, color, FILLED, 8, hierarchy); // } // imshow("【轮廓图】", dst); // Mat hsvImage; // cvtColor(img, hsvImage, COLOR_BGR2HSV); // int hueBinNum = 30;//色调的直方图直条数量 // int saturationBinNum = 32;//饱和度的直方图直条数量 // int histSize[] = {hueBinNum, saturationBinNum}; // float hueRanges[] = {0,180};//定义色调变化范围为0~179 // float saturationRanges[] = {0, 256};//定义饱和度的变化范围为0到255 // const float * ranges[] = {hueRanges, saturationRanges}; // MatND dstHist; // int channels[] = {0, 1}; // calcHist(&hsvImage, 1, channels, Mat(), dstHist, 2, histSize, ranges, true, false); // double maxValue = 0; // minMaxLoc(dstHist, 0, &maxValue, 0, 0); // int scale = 10; // Mat histImg = Mat::zeros(saturationBinNum*scale, hueBinNum*10, CV_8UC3); // for(int hue = 0; hue<hueBinNum;hue++) // { // for(int saturation = 0; saturation<saturationBinNum;saturation++) // { // float binVAlue = dstHist.at<float>(hue, saturation); // int intensity = cvRound(binVAlue*255/maxValue); // rectangle(histImg, Point(hue*scale, saturation*scale), Point((hue+1)*scale-1, (saturation+1)*scale-1), Scalar::all(intensity), FILLED); // } // } // imshow("素材图", img); // imshow("H-S直方图", histImg); // Mat cornerStrength;//进行Harris角点检测 // img = imread("../test.jpg", 0); // cornerStrength = Mat::zeros(img.size(), img.type()); // cornerHarris(img, cornerStrength, 2, 3, 0.01);//有问题,会报错 // Mat harrisCorner; // threshold(cornerStrength, harrisCorner, 0.00001, 255, THRESH_BINARY); // imshow("【角点检测】", harrisCorner); /* 腐蚀操作 */ //Mat element = getStructuringElement(MORPH_RECT, Size(15,15)); //Mat dstIamge; //erode(img, dstIamge, element); //腐蚀图像 //imshow("【效果图】腐蚀操作",dstIamge); //显示腐蚀后的图像 //blur(img, dstIamge, Size(7,7)); //图像均值滤波(模糊) //imshow("均值滤波【效果图】",dstIamge); //显示滤波后的图像 /* Canny边缘检测 */ //Mat grayImage, edge; //cvtColor(img, grayImage, COLOR_BGR2GRAY); //blur(grayImage, edge, Size(3,3)); //先用3x3的内核来降噪 //Canny(edge, edge, 3, 9, 3); //执行Canny边缘检测 //imshow("【效果图】Canny边缘检测", edge); //printf("\t 当前使用的eOpenCV版本为 OpenCV %s",CV_VERSION); //imwrite("../Canny.jpeg", edge); //输出图片文件 //waitKey(0); //等待任意按钮按下 // namedWindow("【滑动条】图像混合"); // g_srcImage1 = imread("../test.jpeg"); // g_srcImage2 = imread("../test1.jpeg"); // g_srcImage1 = g_srcImage1(Rect(0,0,g_srcImage2.cols, g_srcImage2.rows)); // g_nAlphaValueSlider = 70; // char TrackbarName[50]; // sprintf(TrackbarName, "透明值: "); // createTrackbar(TrackbarName, "【滑动条】图像混合", &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar); // on_Trackbar(g_nAlphaValueSlider,0); // // src_Image = imread("../test.jpeg"); // dstImage = Mat::zeros(src_Image.size(), src_Image.type()); // g_nContrastValue = 80; // g_nBrightValue = 80; // namedWindow("【亮度对比度】"); // createTrackbar("对比度:", "【亮度对比度】", &g_nContrastValue, 300, on_ContrastAndBright); // createTrackbar("亮度:", "【亮度对比度】", &g_nBrightValue, 200, on_ContrastAndBright); // on_ContrastAndBright(g_nContrastValue, 0); // on_ContrastAndBright(g_nBrightValue, 0); // // g_rectangle = Rect(-1, -1, 0,0); // Mat tempImage; // img.copyTo(tempImage); // namedWindow("【鼠标绘图】"); // setMouseCallback("【鼠标绘图】",on_MouseHandle, (void *)&img); // // while(1) // { // img.copyTo(tempImage); // if(g_bDrawingBox) // DrawRectangle(tempImage, g_rectangle); //当进行绘制的标识符为真,则进行绘制 // imshow("【鼠标绘图】",tempImage); // if(waitKey(10) == 27) break; // } waitKey(0); return 0; }
代码里面主要是一些图像处理API及其用法,需要的时候来参考就行。
要实现嵌入式视觉开发,首先得把最强大最经典的OpenCV学会。
我参考的是毛星云主编的《OpenCV3编程入门》,过了一遍,记录了我比较关注的内容。学习时编写的源码如下:
代码里面主要是一些图像处理API及其用法,需要的时候来参考就行。