1 static class MorphologyOperationsExample { 2 // OpenCV更多的形态转化 3 /* 4 开盘: 5 先侵蚀 后扩张 dst = open(src, element) = dilate(erode(src, element)) 6 去除亮色小物体 7 闭幕: 8 先扩张 后侵蚀 dst = close(src, element) = erode(dilate(src, element)) 9 去除暗区小孔 10 形态梯度: 11 dst = morph_grad(src, element) = dilate(src, element) - erode(src, element) 12 找到对象轮廓 13 顶帽: 14 dst = tophat(src, element) = src - open(src, element) 15 黑帽: 16 dst = blackhat(src, element) = close(src, element) - src 17 */ 18 19 public: 20 static int showExample(string imageName) { 21 src = cv::imread(imageName, cv::IMREAD_COLOR); 22 23 if (src.empty()) 24 return -1; 25 26 cv::namedWindow("Morphology Transformations Demo", cv::WINDOW_AUTOSIZE); 27 cv::createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", "Morphology Transformations Demo", &morphOperator, maxOperator, MorphologyOperations); 28 cv::createTrackbar("Element:\n 0: Rect - 1: Cross - 2: Ellipse", "Morphology Transformations Demo", &morphElem, maxElem, MorphologyOperations); 29 cv::createTrackbar("Kernel size:\n 2n + 1", "Morphology Transformations Demo", &morphSize, maxKernelSize, MorphologyOperations); 30 MorphologyOperations(0, 0); 31 cv::waitKey(0); 32 return 0; 33 } 34 35 static void MorphologyOperations(int, void*) { 36 // Since MORPH_X : 2 3 4 5 6 37 int operation = morphOperator + 2; 38 cv::Mat element = cv::getStructuringElement(morphElem, cv::Size(2 * morphSize + 1, 2 * morphSize + 1), cv::Point(morphSize, morphSize)); 39 // cv::morphologyEx() 通过operation控制做什么操作 40 // https://docs.opencv.org/4.2.0/d4/d86/group__imgproc__filter.html#gga7be549266bad7b2e6a04db49827f9f32a08d3cc3a2ace00cec488966d31fa29ea 41 cv::morphologyEx(src, dst, operation, element); 42 /* 43 enum cv::MorphShapes { 44 cv::MORPH_RECT = 0, 45 cv::MORPH_CROSS = 1, 46 cv::MORPH_ELLIPSE = 2 47 } 48 49 enum cv::MorphTypes { 50 cv::MORPH_ERODE = 0, 51 cv::MORPH_DILATE = 1, 52 cv::MORPH_OPEN = 2, 53 cv::MORPH_CLOSE = 3, 54 cv::MORPH_GRADIENT = 4, 55 cv::MORPH_TOPHAT = 5, 56 cv::MORPH_BLACKHAT = 6, 57 cv::MORPH_HITMISS = 7 58 } 59 */ 60 cv::imshow("Morphology Transformations Demo", dst); 61 } 62 63 // 需要在类外初始化 64 static cv::Mat src; 65 static cv::Mat dst; 66 static int morphElem; // = 0 67 static int morphSize; // = 0 68 static int morphOperator; // = 0 69 static int const maxOperator = 4; 70 static int const maxElem = 2; 71 static int const maxKernelSize = 21; 72 }; 73 74 int MorphologyOperationsExample::morphElem = 0; 75 int MorphologyOperationsExample::morphSize = 0; 76 int MorphologyOperationsExample::morphOperator = 0; 77 cv::Mat MorphologyOperationsExample::src; 78 cv::Mat MorphologyOperationsExample::dst; 79 80 int useThisMorphologyOperationsExample(void) { 81 MorphologyOperationsExample::showExample("blackWord.png"); 82 83 cv::waitKey(0); 84 return 0; 85 }
1 int exampleHist_or_Miss(void) { 2 // Hit-or-Miss变换 3 // 创建输入图片 4 cv::Mat inputImage = (cv::Mat_<uchar>(8, 8) << 5 0, 0, 0, 0, 0, 0, 0, 0, 6 0, 255, 255, 255, 0, 0, 0, 255, 7 0, 255, 255, 255, 0, 0, 0, 0, 8 0, 255, 255, 255, 0, 255, 0, 0, 9 0, 0, 255, 0, 0, 0, 0, 0, 10 0, 0, 255, 0, 0, 255, 255, 0, 11 0, 255, 0, 255, 0, 0, 255, 0, 12 0, 255, 255, 255, 0, 0, 0, 0); 13 14 cv::Mat kernel = (cv::Mat_<int>(3, 3) << 15 0, 1, 0, 16 1, -1, 1, 17 0, 1, 0); 18 19 cv::Mat outputImage; 20 cv::morphologyEx(inputImage, outputImage, cv::MORPH_HITMISS, kernel); 21 const int rate = 10; 22 kernel = (kernel + 1) * 127; 23 kernel.convertTo(kernel, CV_8U); 24 cv::resize(kernel, kernel, cv::Size(), rate, rate, cv::INTER_NEAREST); 25 cv::imshow("kernel", kernel); 26 cv::resize(inputImage, inputImage, cv::Size(), rate, rate, cv::INTER_NEAREST); 27 cv::imshow("Original", inputImage); 28 cv::resize(outputImage, outputImage, cv::Size(), rate, rate, cv::INTER_NEAREST); 29 cv::imshow("Hit or Miss", outputImage); 30 31 cv::waitKey(0); 32 return 0; 33 }
1 int getHVExample(void) { 2 // 使用形态学操作来提取水平和垂直线 3 cv::Mat src = cv::imread("melody.png", cv::IMREAD_COLOR); 4 5 if (src.empty()) { 6 std::cout << "Read Failed!" << std::endl; 7 return -1; 8 } 9 10 cv::imshow("Src", src); 11 cv::Mat gray; 12 13 if (src.channels() == 3) { 14 cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY); 15 } 16 else { 17 gray = src; 18 } 19 20 cv::imshow("Gray", gray); 21 cv::Mat bw; 22 // 自适应阈值化函数adaptiveThreshold来实现自适应阈值处理 23 // https://blog.csdn.net/wenhao_ir/article/details/51565517 24 cv::adaptiveThreshold(~gray, bw, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 15, -2); 25 cv::imshow("Binary", bw); 26 27 cv::Mat horizontal = bw.clone(); 28 cv::Mat vertical = bw.clone(); 29 30 int horizontalsize = horizontal.cols / 30; 31 cv::Mat horizontalStructure = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(horizontalsize, 1)); 32 cv::erode(horizontal, horizontal, horizontalStructure, cv::Point(-1, -1)); 33 cv::dilate(horizontal, horizontal, horizontalStructure, cv::Point(-1, -1)); 34 cv::imshow("Horizontal", horizontal); 35 36 int verticalsize = vertical.rows / 30; 37 cv::Mat verticalStructure = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, verticalsize)); 38 cv::erode(vertical, vertical, verticalStructure, cv::Point(-1, -1)); 39 cv::dilate(vertical, vertical, verticalStructure, cv::Point(-1, -1)); 40 cv::imshow("Vertical", vertical); 41 42 // 对二进制图像进行非操作 43 // https://blog.csdn.net/u011028345/article/details/77278467 44 cv::bitwise_not(vertical, vertical); 45 cv::imshow("vertical_bit", vertical); 46 47 // 扩张边界 平滑图像 48 // 1 extract edges 49 cv::Mat edges; 50 cv::adaptiveThreshold(vertical, edges, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 3, -2); 51 cv::imshow("Edges", edges); 52 // 2 dilate edges 53 cv::Mat kernel = cv::Mat::ones(2, 2, CV_8UC1); 54 cv::dilate(edges, edges, kernel); 55 cv::imshow("dilate", edges); 56 // 3 src.copyTo(smooth) 57 cv::Mat smooth; 58 vertical.copyTo(smooth); 59 // 4 blur smooth img 60 // blur()函数可以用标准化的盒式过滤器来平滑图像。 61 // https://blog.csdn.net/duwangthefirst/article/details/79971322 62 cv::blur(smooth, smooth, cv::Size(2, 2)); 63 // 5 smooth.copyTo(src, edges) 64 smooth.copyTo(vertical, edges); 65 cv::imshow("smooth", vertical); 66 67 68 cv::waitKey(0); 69 return 0; 70 }
1 int showPyramidsDemo(void) { 2 // 图像金字塔 3 // 将图像转化为与原始图像不同的大小 放大/缩小 4 // 高斯金字塔:较常用,用于缩减图像 5 // 拉普拉斯金字塔:从金字塔中较低的图像重建上采样图像(分辨率较低) 6 cv::Mat src; 7 cv::Mat dst; 8 cv::Mat tmp; 9 10 src = cv::imread("small.jpg", cv::IMREAD_COLOR); 11 if (src.empty()) { 12 std::cout << "Failed read!" << std::endl; 13 return -1; 14 } 15 16 tmp = src; 17 dst = tmp; 18 cv::imshow("Pyramids Demo", src); 19 20 cv::pyrUp(src, dst, cv::Size(src.cols * 2, src.rows * 2)); 21 cv::imshow("Up Demo", dst); 22 //tmp = dst; 23 24 cv::pyrDown(src, tmp, cv::Size(src.cols / 2, src.rows / 2)); 25 cv::imshow("Down Demo", tmp); 26 //tmp = dst; 27 /* 28 while (true) { 29 char c = cv::waitKey(0); 30 31 if (c == 27) 32 break; 33 if (c == ‘u‘) { 34 cv::pyrUp(tmp, dst, cv::Size(tmp.cols * 2, tmp.rows * 2)); 35 std::cout << "Zoom In: Image * 2" << std::endl; 36 } 37 if (c == ‘d‘) { 38 cv::pyrDown(tmp, dst, cv::Size(tmp.cols / 2, tmp.rows / 2)); 39 std::cout << "Zoom Out: Image / 2" << std::endl; 40 } 41 42 cv::imshow("Pyramids Demo", dst); 43 tmp = dst; 44 } 45 */ 46 cv::waitKey(0); 47 return 0; 48 }
OpenCV学习(6)--更多形态转化、Hit-or-Miss变换、Hit-or-Miss变换、图像金字塔
原文:https://www.cnblogs.com/lnlin/p/13777804.html