1. 用OpenCV验证腐蚀和膨胀,只需截图回复。具体做法可参考何东健课件和源代码的第6章或其他资源。
2. 用OpenCV验证细化,只需截图回复。具体做法可参考何东健课件和源代码的第6章或其他资源。
3. 其他方法,可先了解基本原理,数学推导知道即可。
算法理论文章: https://blog.csdn.net/baidu_21578557/article/details/51871134
用OpenCV验证腐蚀和膨胀
1public class threshold { 2 3 private final static String path = System.getProperty("user.dir") + "\\catton.jpg"; 4 5 static { 6 platformUtils.loadLibraries(); 7 } 8 9 10 public static void main(String[] args) { 11 12 Mat src= Imgcodecs.imread(path); 13 14 Mat dest=new Mat(); 15 16 Imgproc.threshold(src,dest,100,500,Imgproc.THRESH_BINARY); 17 18 //获取数据 19 byte [] data=new byte[dest.rows()*dest.cols()*(int)dest.elemSize()]; 20 dest.get(0,0,data); 21 22 //转为二值化image buffer作为存储对象 可以存储二进制 也可以存储灰度化图像 23 BufferedImage bufferedImage=new BufferedImage(dest.cols(),dest.rows(),BufferedImage.TYPE_BYTE_GRAY); 24 25 bufferedImage.getRaster().setDataElements(0,0,dest.cols(),dest.rows(),data); 26 27 JFrame frame=new JFrame(); 28 frame.getContentPane().add(new JLabel(new ImageIcon(bufferedImage))); 29 frame.pack(); 30 frame.setVisible(true); 31 32 33 HighGui.imshow(" threshold image",dest); 34 HighGui.waitKey(0); 35 } 36}
用OpenCV验证细化
1//提取图像的骨架 2void ImgThin(cv::Mat src,int maxIterations=-1) 3{ 4 if (src.empty()) return;//图像为空,直接返回 5 cv::threshold(src, src, m_dThreshold, 1, CV_THRESH_BINARY);//转为0或1的图像 6 7 int ImgHeight = src.rows; 8 int ImgWidth = src.cols; 9 10 int count = 0; //记录迭代次数 11 while (true) 12 { 13 count++; 14 if (maxIterations != -1 && count > maxIterations) //限制次数并且迭代次数到达 15 break; 16 17 vector<pair<int, int> > mFlag; //用于标记需要删除的点 18 //对点标记 19 for (int i = 0; i < ImgHeight; ++i) 20 { 21 for (int j = 0; j < ImgWidth; ++j) 22 { 23 //如果满足四个条件,进行标记 24 // p9 p2 p3 25 // p8 p1 p4 26 // p7 p6 p5 27 int p1 = src.at<uchar>(i, j); 28 int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j); 29 int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1); 30 int p4 = (j == ImgWidth - 1) ? 0 : src.at<uchar>(i, j + 1); 31 int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i + 1, j + 1); 32 int p6 = (i == ImgHeight - 1) ? 0 : src.at<uchar>(i + 1, j); 33 int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.at<uchar>(i + 1, j - 1); 34 int p8 = (j == 0) ? 0 : src.at<uchar>(i, j - 1); 35 int p9 = (i == 0 || j == 0) ? 0 : src.at<uchar>(i - 1, j - 1); 36 37 if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6) 38 { 39 int ap = 0; 40 if (p2 == 0 && p3 == 1) ++ap; 41 if (p3 == 0 && p4 == 1) ++ap; 42 if (p4 == 0 && p5 == 1) ++ap; 43 if (p5 == 0 && p6 == 1) ++ap; 44 if (p6 == 0 && p7 == 1) ++ap; 45 if (p7 == 0 && p8 == 1) ++ap; 46 if (p8 == 0 && p9 == 1) ++ap; 47 if (p9 == 0 && p2 == 1) ++ap; 48 49 if (ap == 1) 50 { 51 if (p2*p4*p6 == 0) 52 { 53 if (p4*p6*p8 == 0) 54 { 55 //标记 56 mFlag.push_back(make_pair(i, j)); 57 } 58 } 59 } 60 } 61 } 62 } 63 64 //将标记的点删除 65 for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i) 66 { 67 src.at<uchar>(i->first, i->second) = 0; 68 } 69 70 //直到没有点满足,算法结束 71 if (mFlag.size() == 0) break; 72 else mFlag.clear();//将mFlag清空 73 74 //对点标记 75 for (int i = 0; i < ImgHeight; ++i) 76 { 77 for (int j = 0; j < ImgWidth; ++j) 78 { 79 //如果满足四个条件,进行标记 80 // p9 p2 p3 81 // p8 p1 p4 82 // p7 p6 p5 83 int p1 = src.at<uchar>(i, j); 84 if (p1 != 1) continue; 85 int p2 = (i == 0) ? 0 : src.at<uchar>(i - 1, j); 86 int p3 = (i == 0 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i - 1, j + 1); 87 int p4 = (j == ImgWidth - 1) ? 0 : src.at<uchar>(i, j + 1); 88 int p5 = (i == ImgHeight - 1 || j == ImgWidth - 1) ? 0 : src.at<uchar>(i + 1, j + 1); 89 int p6 = (i == ImgHeight - 1) ? 0 : src.at<uchar>(i + 1, j); 90 int p7 = (i == ImgHeight - 1 || j == 0) ? 0 : src.at<uchar>(i + 1, j - 1); 91 int p8 = (j == 0) ? 0 : src.at<uchar>(i, j - 1); 92 int p9 = (i == 0 || j == 0) ? 0 : src.at<uchar>(i - 1, j - 1); 93 94 if ((p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) >= 2 && (p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) <= 6) 95 { 96 int ap = 0; 97 if (p2 == 0 && p3 == 1) ++ap; 98 if (p3 == 0 && p4 == 1) ++ap; 99 if (p4 == 0 && p5 == 1) ++ap; 100 if (p5 == 0 && p6 == 1) ++ap; 101 if (p6 == 0 && p7 == 1) ++ap; 102 if (p7 == 0 && p8 == 1) ++ap; 103 if (p8 == 0 && p9 == 1) ++ap; 104 if (p9 == 0 && p2 == 1) ++ap; 105 106 if (ap == 1) 107 { 108 if (p2*p4*p8 == 0) 109 { 110 if (p2*p6*p8 == 0) 111 { 112 //标记 113 mFlag.push_back(make_pair(i, j)); 114 } 115 } 116 } 117 } 118 } 119 } 120 //删除 121 for (vector<pair<int, int> >::iterator i = mFlag.begin(); i != mFlag.end(); ++i) 122 { 123 src.at<uchar>(i->first, i->second) = 0; 124 } 125 126 //直到没有点满足,算法结束 127 if (mFlag.size() == 0) break; 128 else mFlag.clear();//将mFlag清空 129 } 130 131 cv::threshold(src, src, 0, 255, CV_THRESH_BINARY);//二值化图像 132}
