原生C++写一个canny边缘检测
时间: 2023-10-23 21:15:17 浏览: 97
以下是一个简单的Canny边缘检测的实现:
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define WIDTH 512
#define HEIGHT 512
#define THRESHOLD_LOW 50
#define THRESHOLD_HIGH 150
unsigned char input_image[WIDTH][HEIGHT];
unsigned char output_image[WIDTH][HEIGHT];
int sobel_x[3][3] = {
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1}
};
int sobel_y[3][3] = {
{1, 2, 1},
{0, 0, 0},
{-1, -2, -1}
};
void read_image(char *filename, unsigned char image[][HEIGHT])
{
FILE *fp;
if ((fp = fopen(filename, "rb")) == NULL) {
printf("Error opening file %s\n", filename);
exit(1);
}
fread(image, sizeof(unsigned char), WIDTH * HEIGHT, fp);
fclose(fp);
}
void write_image(char *filename, unsigned char image[][HEIGHT])
{
FILE *fp;
if ((fp = fopen(filename, "wb")) == NULL) {
printf("Error opening file %s\n", filename);
exit(1);
}
fwrite(image, sizeof(unsigned char), WIDTH * HEIGHT, fp);
fclose(fp);
}
void apply_sobel(unsigned char input[][HEIGHT], int x_filter[][3], int y_filter[][3], unsigned char output[][HEIGHT])
{
int i, j, x, y, gx, gy, g;
int max_gradient = 0;
for (i = 1; i < WIDTH - 1; i++) {
for (j = 1; j < HEIGHT - 1; j++) {
gx = 0;
gy = 0;
for (x = -1; x <= 1; x++) {
for (y = -1; y <= 1; y++) {
gx += input[i+x][j+y] * x_filter[x+1][y+1];
gy += input[i+x][j+y] * y_filter[x+1][y+1];
}
}
g = sqrt(gx*gx + gy*gy);
if (g > max_gradient) {
max_gradient = g;
}
output[i][j] = g;
}
}
for (i = 1; i < WIDTH - 1; i++) {
for (j = 1; j < HEIGHT - 1; j++) {
output[i][j] = (output[i][j] * 255) / max_gradient;
}
}
}
void apply_non_maximum_suppression(unsigned char input[][HEIGHT], unsigned char gradient[][HEIGHT], unsigned char output[][HEIGHT])
{
int i, j;
unsigned char a, b, c, d;
for (i = 1; i < WIDTH - 1; i++) {
for (j = 1; j < HEIGHT - 1; j++) {
if (gradient[i][j] == 0) {
output[i][j] = 0;
} else {
a = gradient[i-1][j];
b = gradient[i+1][j];
c = gradient[i][j-1];
d = gradient[i][j+1];
if (gradient[i][j] >= a && gradient[i][j] >= b && gradient[i][j] >= c && gradient[i][j] >= d) {
output[i][j] = gradient[i][j];
} else {
output[i][j] = 0;
}
}
}
}
}
void apply_hysteresis(unsigned char input[][HEIGHT], unsigned char output[][HEIGHT])
{
int i, j, x, y;
unsigned char temp[WIDTH][HEIGHT];
for (i = 0; i < WIDTH; i++) {
for (j = 0; j < HEIGHT; j++) {
temp[i][j] = input[i][j];
}
}
for (i = 1; i < WIDTH - 1; i++) {
for (j = 1; j < HEIGHT - 1; j++) {
if (temp[i][j] >= THRESHOLD_HIGH) {
output[i][j] = 255;
for (x = -1; x <= 1; x++) {
for (y = -1; y <= 1; y++) {
if (temp[i+x][j+y] >= THRESHOLD_LOW && output[i+x][j+y] == 0) {
apply_hysteresis(temp, output, i+x, j+y);
}
}
}
}
}
}
}
int main()
{
read_image("input.raw", input_image);
apply_sobel(input_image, sobel_x, sobel_y, output_image);
apply_non_maximum_suppression(input_image, output_image, output_image);
apply_hysteresis(output_image, output_image);
write_image("output.raw", output_image);
return 0;
}
```
该实现包括以下步骤:
1. 读取输入图像。
2. 应用Sobel算子计算梯度图像。
3. 应用非最大值抑制,去除非边缘像素。
4. 应用双阈值滞后边缘连接算法,将像素分类为强边缘、弱边缘或非边缘。
5. 将强边缘像素加入输出图像,将弱边缘像素加入输出图像,如果弱边缘像素与强边缘像素相邻,则将其也加入输出图像。
6. 将输出图像写入文件。
阅读全文