OpenCV学习(7)--
阈值操作:
1 class ThresholdDemoExamlpe { 2 // 阈值操作 3 public: 4 //static int thresholdValue = 0; 5 //static int thresholdType = 3; 6 //static int const maxValue = 255; 7 static int thresholdValue; 8 static int thresholdType; 9 static int const maxValue; 10 static int const maxType = 4; 11 static int const maxBINARYvalue = 255; 12 static cv::Mat src; 13 static cv::Mat src_gray; 14 static cv::Mat dst; 15 16 static void ThresholdDemo(int, void*) { 17 // 0: Binary 18 // 1: Binary Inverted 19 // 2: Threshold Truncated 20 // 3: Threshold to Zero 21 // 4: Threshold to Zero Inverted 22 // 图像二值化 23 // https://blog.csdn.net/u012566751/article/details/77046445 24 cv::threshold(src_gray, dst, thresholdValue, maxBINARYvalue, thresholdType); 25 cv::imshow("Threshold Demo", dst); 26 } 27 28 int show(void) { 29 src = cv::imread("dog.jpg", cv::IMREAD_COLOR); 30 if (src.empty()) 31 return -1; 32 33 cv::cvtColor(src, src_gray, cv::COLOR_BGR2GRAY); // 转化为灰度图像 34 cv::namedWindow("Threshold Demo", cv::WINDOW_AUTOSIZE); 35 cv::createTrackbar("Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted", "Threshold Demo", &thresholdType, maxType, ThresholdDemo); 36 cv::createTrackbar("Value", "Threshold Demo", &thresholdValue, maxValue, ThresholdDemo); 37 ThresholdDemo(0, 0); 38 39 cv::waitKey(0); 40 return 0; 41 } 42 43 };
Object detection:
1 class ObjectDetection { 2 public: 3 static int low_r; 4 static int low_g; 5 static int low_b; 6 static int high_r; 7 static int high_g; 8 static int high_b; 9 10 static void on_low_r_thresh_trackbar(int, void*) { 11 low_r = min(high_r - 1, low_r); 12 // openCV提供createTrackbar指定图像窗口创建一个指定名称和范围的滑动条,使用户能够滑动调整输入,然后根据输入值执行程序。 13 // 还提供了getTrackbarPos和setTrackbarPos以获取和修改bar的当前值。 14 // https://blog.csdn.net/u010963435/article/details/78682725 15 cv::setTrackbarPos("Low R", "Object Detection", low_r); 16 } 17 18 static void on_high_r_thresh_trackbar(int, void*) { 19 high_r = min(high_r, low_r + 1); 20 cv::setTrackbarPos("High R", "Object Detection", high_r); 21 } 22 23 static void on_low_g_thresh_trackbar(int, void*) { 24 low_g = min(high_g - 1, low_g); 25 cv::setTrackbarPos("Low G", "Object Detection", low_g); 26 } 27 28 static void on_high_g_thresh_trackbar(int, void*) { 29 high_g = min(high_g, low_g + 1); 30 cv::setTrackbarPos("High G", "Object Detection", high_g); 31 } 32 33 static void on_low_b_thresh_trackbar(int, void*) { 34 low_b = min(high_b - 1, low_b); 35 cv::setTrackbarPos("Low B", "Object Detection", low_b); 36 } 37 38 static void on_high_b_thresh_trackbar(int, void*) { 39 high_b = min(high_b, low_b + 1); 40 cv::setTrackbarPos("High B", "Object Detection", high_b); 41 } 42 43 static int show() { 44 cv::Mat frame, frame_threshold; 45 //cv::VideoCapture cap(0); // //视频捕捉设备 id ---笔记本电脑的用0表示 46 frame = cv::imread("angel.jpg", cv::IMREAD_COLOR); 47 cv::namedWindow("Video Capture", cv::WINDOW_NORMAL); 48 cv::namedWindow("Object Detection", cv::WINDOW_NORMAL); 49 50 // 创建滑动条 设定阈值 51 cv::createTrackbar("Low R", "Object Detection", &low_r, 255, on_low_r_thresh_trackbar); 52 cv::createTrackbar("HIgh R", "Object Detection", &high_r, 255, on_high_r_thresh_trackbar); 53 cv::createTrackbar("Low G", "Object Detection", &low_g, 255, on_low_g_thresh_trackbar); 54 cv::createTrackbar("HIgh G", "Object Detection", &high_g, 255, on_high_g_thresh_trackbar); 55 cv::createTrackbar("Low B", "Object Detection", &low_b, 255, on_low_b_thresh_trackbar); 56 cv::createTrackbar("HIgh B", "Object Detection", &high_b, 255, on_high_b_thresh_trackbar); 57 58 //while (true) { 59 //cap >> frame; 60 //if (frame.empty()) 61 //break; 62 63 //cv::inRange(frame, cv::Scalar(low_b, low_g, low_r), cv::Scalar(high_b, high_g, high_r), frame_threshold); 64 //cv::imshow("Video Capture", frame); 65 //cv::imshow("Object Detection", frame_threshold); 66 //} 67 cv::inRange(frame, cv::Scalar(low_b, low_g, low_r), cv::Scalar(high_b, high_g, high_r), frame_threshold); 68 cv::imshow("Video Capture", frame); 69 cv::imshow("Object Detection", frame_threshold); 70 71 return 0; 72 } 73 }; 74 /* 75 int ObjectDetection::low_b = 30; 76 int ObjectDetection::low_g = 30; 77 int ObjectDetection::low_r = 30; 78 int ObjectDetection::high_b = 100; 79 int ObjectDetection::high_g = 100; 80 int ObjectDetection::high_r = 100; 81 */
使用cv::filter2D创建线性过滤器:
1 int createFilterExample(void) { 2 // 使用cv::filter2D创建线性过滤器 3 cv::Mat src, dst, kernel; 4 cv::Point anchor = cv::Point(-1, -1); // 中心点; 5 double delta = 0; 6 int ddepth = -1; 7 int kernelSize; 8 int ind = 0; 9 10 src = cv::imread("small.jpg", cv::IMREAD_COLOR); 11 if (src.empty()) 12 return -1; 13 14 cv::imshow("Src", src); 15 16 kernelSize = 3; 17 kernel = cv::Mat::ones(kernelSize, kernelSize, CV_32F); 18 cv::filter2D(src, dst, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT); 19 cv::imshow("kernel size 3", dst); 20 /* 21 kernelSize = 5; 22 kernel = cv::Mat::ones(kernelSize, kernelSize, CV_32F); 23 cv::filter2D(src, dst, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT); 24 cv::imshow("kernel size 5", dst); 25 26 kernelSize = 7; 27 kernel = cv::Mat::ones(kernelSize, kernelSize, CV_32F); 28 cv::filter2D(src, dst, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT); 29 cv::imshow("kernel size 7", dst); 30 31 kernelSize = 9; 32 kernel = cv::Mat::ones(kernelSize, kernelSize, CV_32F); 33 cv::filter2D(src, dst, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT); 34 cv::imshow("kernel size 9", dst); 35 36 kernelSize = 11; 37 kernel = cv::Mat::ones(kernelSize, kernelSize, CV_32F); 38 cv::filter2D(src, dst, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT); 39 cv::imshow("kernel size 11", dst); 40 */ 41 42 cv::waitKey(0); 43 return 0; 44 }
扩充图像边缘:
1 int makeBorder(void) { 2 // 扩充图像边缘 3 cv::Mat src, dst; 4 src = cv::imread("Lisa.png", cv::IMREAD_COLOR); 5 if (src.empty()) 6 return -1; 7 8 cv::namedWindow("Make Border", cv::WINDOW_AUTOSIZE); 9 int top = (int)(0.05 * src.rows); 10 int bottom = (int)(0.05 * src.rows); 11 int left = (int)(0.05 * src.cols); 12 int right = (int)(0.05 * src.cols); 13 dst = src; 14 cv::imshow("Make Border", dst); 15 cv::RNG rng(12345); 16 cv::Scalar value(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); 17 // 扩充图像边缘 18 // https://blog.csdn.net/qq_22764813/article/details/52787553 19 //cv::copyMakeBorder(src, dst, top, bottom, left, right, cv::BORDER_CONSTANT, value); 20 cv::copyMakeBorder(src, dst, top, bottom, left, right, cv::BORDER_REPLICATE, value); 21 cv::imshow("Make Border", dst); 22 23 cv::waitKey(0); 24 return 0; 25 }
sobel算子的使用:
1 int sobelExample(void) { 2 cv::Mat image, src, src_gray, grad; 3 int ddepth = CV_16S; 4 5 image = cv::imread("Lisa.png", cv::IMREAD_COLOR); 6 if (image.empty()) 7 return -1; 8 9 // 高斯滤波 减少图像中的噪音 10 cv::GaussianBlur(image, src, cv::Size(3, 3), 0, 0, cv::BORDER_DEFAULT); 11 // 转换为灰度图片 12 cv::cvtColor(src, src_gray, cv::COLOR_BGR2GRAY); 13 cv::Mat grad_x, grad_y, abs_grad_x, abs_grad_y; 14 // Gradient X 15 // sobel算子是一种常用的边缘检测算子,是一阶的梯度算法。 16 // https://blog.csdn.net/streamchuanxi/article/details/51542141 17 cv::Sobel(src_gray, grad_x, ddepth, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT); 18 // Gradient Y 19 cv::Sobel(src_gray, grad_y, ddepth, 0, 1, 3, 1, 0, cv::BORDER_DEFAULT); 20 21 cv::convertScaleAbs(grad_x, abs_grad_x); 22 cv::convertScaleAbs(grad_y, abs_grad_y); 23 24 cv::addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad); 25 26 cv::imshow("Sobel Demo", grad); 27 28 29 cv::waitKey(0); 30 return 0; 31 }
拉普拉斯变换示例:
1 int LaplaceOperatorExample(void) { 2 // 拉普拉斯变换 3 cv::Mat src, src_gray, dst; 4 int kernel_size = 3; 5 int scale = 1; 6 int delta = 0; 7 int ddepth = CV_16S; 8 string window_name = "Laplace Demo"; 9 src = cv::imread("Lisa.png", cv::IMREAD_COLOR); 10 if (src.empty()) 11 return -1; 12 13 cv::GaussianBlur(src, src, cv::Size(3, 3), 0, 0, cv::BORDER_DEFAULT); 14 cv::cvtColor(src, src_gray, cv::COLOR_BGR2GRAY); 15 cv::Mat abs_dst; 16 // 拉普拉斯变换 17 cv::Laplacian(src_gray, dst, ddepth, kernel_size, scale, delta, cv::BORDER_DEFAULT); 18 cv::convertScaleAbs(dst, abs_dst); 19 cv::imshow(window_name, abs_dst); 20 21 cv::waitKey(0); 22 return 0; 23 }
Canny边缘检测器使用:
1 int showCanny(void) { 2 // Canny边缘检测器 3 cv::Mat src, src_gray, dst, detected_edges; 4 int lowThreshold = 25; 5 int ratio = 3; 6 int kernel_size = 3; 7 src = cv::imread("small.jpg", cv::IMREAD_COLOR); 8 if (src.empty()) 9 return -1; 10 11 dst.create(src.size(), src.type()); 12 cv::cvtColor(src, src_gray, cv::COLOR_BGR2GRAY); 13 cv::namedWindow("Edge Map", cv::WINDOW_AUTOSIZE); 14 cv::blur(src_gray, detected_edges, cv::Size(3, 3)); 15 // https://blog.csdn.net/u013488563/article/details/18889557 16 cv::Canny(detected_edges, detected_edges, lowThreshold, lowThreshold * ratio, kernel_size); 17 dst = cv::Scalar::all(0); 18 src.copyTo(dst, detected_edges); 19 cv::imshow("Edge Map", dst); 20 21 22 cv::waitKey(0); 23 return 0; 24 }
检测直线和圆:
1 int HoughLineExample(void) { // 运行有点问题 2 // Hough Line变换 用于检测直线 3 cv::Mat src = cv::imread("LineCircle.jpg", cv::IMREAD_COLOR); 4 if (src.empty()) 5 return -1; 6 7 cv::imshow("Src", src); 8 cv::Mat dst, cdst; 9 cv::cvtColor(src, dst, cv::COLOR_BGR2GRAY); 10 cv::imshow("Gray", dst); 11 cv::Canny(dst, cdst, 50, 200, 3); 12 cv::imshow("Canny src", cdst); 13 //cv::cvtColor(dst, cdst, cv::COLOR_GRAY2BGR); 14 //cv::imshow("BGR", cdst); 15 16 vector<cv::Vec2f> lines; 17 cv::HoughLines(cdst, lines, 1, CV_PI / 180, 100, 0, 0); 18 for (int i = 0; i < lines.size(); i++) { 19 float rho = lines[i][0], theta = lines[i][1]; 20 cv::Point pt1, pt2; 21 double a = cos(theta), b = sin(theta); 22 double x0 = a * rho, y0 = b * rho; 23 pt1.x = cvRound(x0 + 1000 * (-b)); 24 pt1.y = cvRound(y0 + 1000 * (a)); 25 pt2.x = cvRound(x0 - 1000 * (-b)); 26 pt2.y = cvRound(y0 - 1000 * (a)); 27 cv::line(cdst, pt1, pt2, cv::Scalar(255, 0, 0), 3, 8); 28 } 29 cv::imshow("detected lines", cdst); 30 31 cv::waitKey(0); 32 return 0; 33 } 34 35 36 37 int DetectCircle(void) { 38 // Hough Circle 检测图像中的圆 39 //cv::Mat image = cv::imread("bowl.jpg", cv::IMREAD_COLOR); 40 cv::Mat image = cv::imread("LineCircle.jpg", cv::IMREAD_COLOR); 41 if (image.empty()) 42 return -1; 43 cv::imshow("Src", image); 44 45 cv::Mat res; 46 res.create(image.size(), image.type()); 47 cv::Mat gray; 48 cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY); 49 cv::imshow("Gray", gray); 50 // 中值滤波 51 cv::medianBlur(gray, gray, 5); 52 vector<cv::Vec3f> circles; 53 // http://www.manongjc.com/article/42132.html 54 cv::HoughCircles(gray, circles, cv::HOUGH_GRADIENT, 1, gray.rows / 16, 100, 30, 50, 300); 55 // 单独一个圆可以检测出来 当圆和其他直线相交 就测出来多个圆 56 57 58 for (int i = 0; i < circles.size(); i++) { 59 cv::Vec3i c = circles[i]; 60 cv::circle(res, cv::Point(c[0], c[1]), c[2], cv::Scalar(0, 0, 255), 3, cv::LINE_AA); 61 cv::circle(res, cv::Point(c[0], c[1]), 2, cv::Scalar(0, 255, 0), 3, cv::LINE_AA); 62 } 63 64 cv::imshow("Detected Circles", res); 65 66 cv::waitKey(0); 67 return 0; 68 }
简单重映射:
1 int RemapExample(void) { 2 // 简单重映射 3 cv::Mat src = cv::imread("dog.jpg", cv::IMREAD_COLOR); 4 cv::Mat dst; 5 dst.create(src.size(), src.type()); 6 cv::Mat map_x, map_y; 7 map_x.create(src.size(), CV_32FC1); 8 map_y.create(src.size(), CV_32FC1); 9 cv::namedWindow("Remap demo", cv::WINDOW_AUTOSIZE); 10 11 for (int j = 0; j < src.rows; j++) { 12 for (int i = 0; i < src.cols; i++) { 13 // 上下翻转 14 //map_x.at<float>(j, i) = (float)i; 15 //map_y.at<float>(j, i) = (float)(src.rows - j); 16 17 // 左右翻转 18 //map_x.at<float>(j, i) = (float)(src.cols - i); 19 //map_y.at<float>(j, i) = (float)j; 20 21 // 上下左右都翻转 22 //map_x.at<float>(j, i) = (float)(src.cols - i); 23 //map_y.at<float>(j, i) = (float)(src.rows - j); 24 25 // 缩小 26 if (i > src.cols * 0.25 && i < src.cols * 0.75 && j > src.rows * 0.25 && j < src.rows * 0.75) { 27 map_x.at<float>(j, i) = 2 * (i - src.cols * 0.25f) + 0.5f; 28 map_y.at<float>(j, i) = 2 * (j - src.rows * 0.25f) + 0.5f; 29 } 30 else { 31 map_x.at<float>(j, i) = 0; 32 map_y.at<float>(j, i) = 0; 33 } 34 } 35 } 36 37 // https://blog.csdn.net/sss_369/article/details/52983123 38 // cv::remap()就是对原图像各个像素点改变位置 39 cv::remap(src, dst, map_x, map_y, cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0)); 40 cv::imshow("Remap demo", dst); 41 42 43 cv::waitKey(0); 44 return 0; 45 }
转载请注明出处