// Thin(Skeleton).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <opencv2/opencv.hpp>
//https://blog.csdn.net/hehedadaq/article/details/80303218
//https://www.cnblogs.com/xianglan/archive/2011/01/01/1923779.html
#define OPT 1
void thin(const cv::Mat &src, cv::Mat &dst) {
int rows = src.rows;
int cols = src.cols;
// 映射表
uchar array[] = { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0,
1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0
};
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
uchar v = src.at<uchar>(r, c);
if (v == 0) {
//uchar a[9] = { 1 }; ///< 注意,这样只初始化了第一项
uchar a[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
// 如果 3 * 3 矩阵的点不在边界且这些值为 0,也就是黑色的点
int posy = r - 1 + k;
int posx = c - 1 + l;
if (-1 < (posy) && (posy) < rows &&
-1 < (posx) && (posx) < cols &&
dst.at<uchar>(posy, posx) == 0) {
a[k * 3 + l] = 0;
}
}
}
/// @test
//for (int i = 0; i < 9; i++)
//{
// std::cout << a[i] << " ";
//}
//std::cout << std::endl;
// 然后根据 array 表,对 dst 的那一点进行赋值
/// 注意没有 a[4]
int sum = a[0] * 1 + a[1] * 2 + a[2] * 4 + a[3] * 8 + a[5] * 16 + a[6] * 32 + a[7] * 64 + a[8] * 128;
//std::cout << "sum: " << sum << std::endl;
dst.at<uchar>(r, c) = array[sum] * 255;
}
}
}
}
void thinH(const cv::Mat &src, cv::Mat &dst) {
int rows = src.rows;
int cols = src.cols;
// 映射表
uchar array[] = { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0,
1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0
};
uchar NEXT = 1;
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
if (NEXT == 0) {
NEXT = 1;
} else {
int M = 1;
if (i > 0 && i < rows - 1)
M = src.at<uchar>(i - 1, j) + src.at<uchar>(i, j) + src.at<uchar>(i + 1, j);
if (src.at<uchar>(i, j) == 0 && M != 0) {
uchar a[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
// 如果 3 * 3 矩阵的点不在边界且这些值为 0,也就是黑色的点
int posy = i - 1 + k;
int posx = j - 1 + l;
if (-1 < (posy) && (posy) < rows &&
-1 < (posx) && (posx) < cols &&
dst.at<uchar>(posy, posx) == 255) {
a[k * 3 + l] = 1;
}
}
}
int sum = a[0] * 1 + a[1] * 2 + a[2] * 4 + a[3] * 8 + a[5] * 16 + a[6] * 32 + a[7] * 64 + a[8] * 128;
dst.at<uchar>(i, j) = array[sum] * 255;
if (array[sum] == 1)
NEXT = 0;
}
}
}
}
}
void thinV(const cv::Mat &src, cv::Mat &dst) {
int rows = src.rows;
int cols = src.cols;
// 映射表
uchar array[] = { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0,
1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0
};
uchar NEXT = 1;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (NEXT == 0) {
NEXT = 1;
} else {
int M = 1;
if (j > 0 && j <cols - 1)
M = src.at<uchar>(i, j - 1) + src.at<uchar>(i, j) + src.at<uchar>(i, j + 1);
if (src.at<uchar>(i, j) == 0 && M != 0) {
uchar a[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
// 如果 3 * 3 矩阵的点不在边界且这些值为 0,也就是黑色的点
int posy = i - 1 + k;
int posx = j - 1 + l;
if (-1 < (posy) && (posy) < rows &&
- 1
- 2
前往页