请用C代码或C++代码,实现两种骨架提取算法:顺序细化和北、南、东、西提取算法。
时间: 2023-12-03 09:46:58 浏览: 50
顺序细化算法的C++代码实现如下:
```c++
#include <iostream>
#include <vector>
using namespace std;
// 顺序细化算法
void seqThin(vector<vector<int>>& image)
{
int height = image.size();
int width = image[0].size();
// 循环次数
int count = 0;
while (true) {
++count;
// 标记需要删除的点
vector<pair<int, int>> toDelete;
// 从上往下扫描
for (int i = 1; i < height - 1; ++i) {
for (int j = 1; j < width - 1; ++j) {
if (image[i][j] == 0) {
continue;
}
int A = (image[i-1][j] == 0) ? 0 : 1;
int B = (image[i-1][j+1] == 0) ? 0 : 1;
int C = (image[i][j+1] == 0) ? 0 : 1;
int D = (image[i+1][j+1] == 0) ? 0 : 1;
int E = (image[i+1][j] == 0) ? 0 : 1;
int F = (image[i+1][j-1] == 0) ? 0 : 1;
int G = (image[i][j-1] == 0) ? 0 : 1;
int H = (image[i-1][j-1] == 0) ? 0 : 1;
int p1 = A + B + C + D + E + F + G + H;
int p2 = (!A && B) + (!B && C) + (!C && D) + (!D && E) +
(!E && F) + (!F && G) + (!G && H) + (!H && A);
int p3 = (A || B || !C) && (D || E || !C) &&
(!A || !D || !G) && (!B || !E || !G);
if (p1 >= 2 && p1 <= 6 && p2 == 1 && p3) {
toDelete.push_back(make_pair(i, j));
}
}
}
// 删除标记的点
for (auto& p : toDelete) {
image[p.first][p.second] = 0;
}
// 标记需要删除的点
toDelete.clear();
// 从下往上扫描
for (int i = height - 2; i >= 1; --i) {
for (int j = width - 2; j >= 1; --j) {
if (image[i][j] == 0) {
continue;
}
int A = (image[i-1][j] == 0) ? 0 : 1;
int B = (image[i-1][j+1] == 0) ? 0 : 1;
int C = (image[i][j+1] == 0) ? 0 : 1;
int D = (image[i+1][j+1] == 0) ? 0 : 1;
int E = (image[i+1][j] == 0) ? 0 : 1;
int F = (image[i+1][j-1] == 0) ? 0 : 1;
int G = (image[i][j-1] == 0) ? 0 : 1;
int H = (image[i-1][j-1] == 0) ? 0 : 1;
int p1 = A + B + C + D + E + F + G + H;
int p2 = (!A && B) + (!B && C) + (!C && D) + (!D && E) +
(!E && F) + (!F && G) + (!G && H) + (!H && A);
int p3 = (A || B || !C) && (D || E || !C) &&
(!A || !D || !G) && (!B || !E || !G);
if (p1 >= 2 && p1 <= 6 && p2 == 1 && p3) {
toDelete.push_back(make_pair(i, j));
}
}
}
// 删除标记的点
for (auto& p : toDelete) {
image[p.first][p.second] = 0;
}
// 如果没有点被删除,退出循环
if (toDelete.empty()) {
break;
}
}
cout << "循环次数:" << count << endl;
}
int main()
{
vector<vector<int>> image = {
{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, 0, 0, 0},
{0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0}
};
seqThin(image);
for (auto& row : image) {
for (auto& pixel : row) {
cout << pixel << " ";
}
cout << endl;
}
return 0;
}
```
北、南、东、西提取算法的C代码实现如下:
```c
#include <stdio.h>
#include <stdlib.h>
// 北、南、东、西提取算法
void bnsThin(int** image, int height, int width)
{
// 循环次数
int count = 0;
while (1) {
++count;
// 标记需要删除的点
int toDelete[height * width][2];
int numToDelete = 0;
// 从上往下扫描
for (int i = 1; i < height - 1; ++i) {
for (int j = 1; j < width - 1; ++j) {
if (image[i][j] == 0) {
continue;
}
int A = (image[i-1][j] == 0) ? 0 : 1;
int B = (image[i-1][j+1] == 0) ? 0 : 1;
int C = (image[i][j+1] == 0) ? 0 : 1;
int D = (image[i+1][j+1] == 0) ? 0 : 1;
int E = (image[i+1][j] == 0) ? 0 : 1;
int F = (image[i+1][j-1] == 0) ? 0 : 1;
int G = (image[i][j-1] == 0) ? 0 : 1;
int H = (image[i-1][j-1] == 0) ? 0 : 1;
int p1 = A + B + C + D + E + F + G + H;
int p2 = (!A && B) + (!B && C) + (!C && D) + (!D && E) +
(!E && F) + (!F && G) + (!G && H) + (!H && A);
int p3 = (A || B || !C) && (D || E || !C) &&
(!A || !D || !G) && (!B || !E || !G);
if (p1 >= 2 && p1 <= 6 && p2 == 1 && p3) {
toDelete[numToDelete][0] = i;
toDelete[numToDelete][1] = j;
++numToDelete;
}
}
}
// 删除标记的点
for (int i = 0; i < numToDelete; ++i) {
image[toDelete[i][0]][toDelete[i][1]] = 0;
}
// 标记需要删除的点
numToDelete = 0;
// 从下往上扫描
for (int i = height - 2; i >= 1; --i) {
for (int j = width - 2; j >= 1; --j) {
if (image[i][j] == 0) {
continue;
}
int A = (image[i-1][j] == 0) ? 0 : 1;
int B = (image[i-1][j+1] == 0) ? 0 : 1;
int C = (image[i][j+1] == 0) ? 0 : 1;
int D = (image[i+1][j+1] == 0) ? 0 : 1;
int E = (image[i+1][j] == 0) ? 0 : 1;
int F = (image[i+1][j-1] == 0) ? 0 : 1;
int G = (image[i][j-1] == 0) ? 0 : 1;
int H = (image[i-1][j-1] == 0) ? 0 : 1;
int p1 = A + B + C + D + E + F + G + H;
int p2 = (!A && B) + (!B && C) + (!C && D) + (!D && E) +
(!E && F) + (!F && G) + (!G && H) + (!H && A);
int p3 = (A || B || !C) && (D || E || !C) &&
(!A || !D || !G) && (!B || !E || !G);
if (p1 >= 2 && p1 <= 6 && p2 == 1 && p3) {
toDelete[numToDelete][0] = i;
toDelete[numToDelete][1] = j;
++numToDelete;
}
}
}
// 删除标记的点
for (int i = 0; i < numToDelete; ++i) {
image[toDelete[i][0]][toDelete[i][1]] = 0;
}
// 如果没有点被删除,退出循环
if (numToDelete == 0) {
break;
}
}
printf("循环次数:%d\n", count);
}
int main()
{
int height = 10;
int width = 10;
int** image = (int**)malloc(height * sizeof(int*));
for (int i = 0; i < height; ++i) {
image[i] = (int*)malloc(width * sizeof(int));
for (int j = 0; j < width; ++j) {
image[i][j] = 0;
}
}
image[2][3] = 1;
image[2][4] = 1;
image[3][3] = 1;
image[3][4] = 1;
image[4][5] = 1;
image[5][5] = 1;
image[6][4] = 1;
image[5][3] = 1;
bnsThin(image, height, width);
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
printf("%d ", image[i][j]);
}
printf("\n");
}
for (int i = 0; i < height; ++i) {
free(image[i]);
}
free(image);
return 0;
}
```
注意:这里提供的代码仅作为示例,实际应用中需要根据具体情况进行修改。