必做: bmp图像读取,二值形态学边缘检测,灰度形态学边缘检测。读取bmp图像后,对图像进行边缘检测,并将边缘图像保存为新的bmp图像
8条回答 默认 最新
Watch the clown 2023-06-16 23:49关注我尝试了你的边缘图像,需要告诉你心目中的图像特征要多细腻,我研究图像很多年,总的来说c语言实现效果达不到那么完美,最好要用OpenCV和libbmp实现,边缘检测是得靠模型不断训练得到的,我保留意见
原图
生成图

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #pragma pack(1) typedef struct { unsigned char magic[2]; unsigned int fileSize; unsigned short reserved1; unsigned short reserved2; unsigned int offset; } BMPHeader; typedef struct { unsigned int headerSize; int width; int height; unsigned short planes; unsigned short bitsPerPixel; unsigned int compression; unsigned int imageSize; int xPixelsPerMeter; int yPixelsPerMeter; unsigned int colorsUsed; unsigned int colorsImportant; } BMPInfoHeader; typedef struct { unsigned char blue; unsigned char green; unsigned char red; } RGB; void readBmp(const char* filename, RGB** image, int* width, int* height) { FILE* fp = fopen(filename, "rb"); if (!fp) { printf("Failed to open file: %s\n", filename); exit(1); } BMPHeader header; BMPInfoHeader infoHeader; if (fread(&header, sizeof(header), 1, fp) != 1) { printf("Failed to read BMP header\n"); exit(1); } if (fread(&infoHeader, sizeof(infoHeader), 1, fp) != 1) { printf("Failed to read BMP info header\n"); exit(1); } if (header.magic[0] != 'B' || header.magic[1] != 'M') { printf("Invalid BMP magic number: %c%c\n", header.magic[0], header.magic[1]); exit(1); } if (infoHeader.bitsPerPixel != 24) { printf("Unsupported BMP format: %d bits per pixel\n", infoHeader.bitsPerPixel); exit(1); } if (infoHeader.compression != 0) { printf("Unsupported BMP compression method: %d\n", infoHeader.compression); exit(1); } *width = infoHeader.width; *height = infoHeader.height; *image = (RGB*)malloc(*width * *height * sizeof(RGB)); if (!*image) { printf("Memory allocation failed\n"); exit(1); } int rowSize = (*width * 3 + 3) / 4 * 4 - (*width * 3 % 4); int i, j; for (i = 0; i < *height; i++) { for (j = 0; j < *width; j++) { RGB pixel; if (fread(&pixel, sizeof(pixel), 1, fp) != 1) { printf("Failed to read pixel at (%d, %d)\n", j, i); exit(1); } (*image)[(*height - i - 1) * *width + j] = pixel; } fseek(fp, rowSize - *width * 3, SEEK_CUR); } fclose(fp); } void saveBmp(const char* filename, RGB* image, int width, int height) { FILE* fp = fopen(filename, "wb"); if (!fp) { printf("Failed to create file: %s\n", filename); exit(1); } BMPHeader header; BMPInfoHeader infoHeader; header.magic[0] = 'B'; header.magic[1] = 'M'; header.fileSize = sizeof(header) + sizeof(infoHeader) + (width * height * 3); header.reserved1 = 0; header.reserved2 = 0; header.offset = sizeof(header) + sizeof(infoHeader); infoHeader.headerSize = sizeof(infoHeader); infoHeader.width = width; infoHeader.height = height; infoHeader.planes = 1; infoHeader.bitsPerPixel = 24; infoHeader.compression = 0; infoHeader.imageSize = width * height * 3; infoHeader.xPixelsPerMeter = 0; infoHeader.yPixelsPerMeter = 0; infoHeader.colorsUsed = 0; infoHeader.colorsImportant = 0; if (fwrite(&header, sizeof(header), 1, fp) != 1) { printf("Failed to write BMP header\n"); exit(1); } if (fwrite(&infoHeader, sizeof(infoHeader), 1, fp) != 1) { printf("Failed to write BMP info header\n"); exit(1); } int rowSize = (width * 3 + 3) / 4 * 4 - (width * 3 % 4); int i, j; for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { RGB pixel = image[(height - i - 1) * width + j]; if (fwrite(&pixel, sizeof(pixel), 1, fp) != 1) { printf("Failed to write pixel at (%d, %d)\n", j, i); exit(1); } } unsigned char padding[3] = {0}; if (fwrite(padding, sizeof(padding), 1, fp) != 1) { printf("Failed to write padding\n"); exit(1); } } fclose(fp); printf("图像处理成功!\n"); } void gray(RGB* image, int width, int height) { int i, j; for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { unsigned char gray = (unsigned char)(0.299 * image[width*i + j].red + 0.587 * image[width*i + j].green + 0.114 * image[width*i + j].blue); image[width*i + j].red = gray; image[width*i + j].green = gray; image[width*i + j].blue = gray; } } } void binarize(RGB* image, int width, int height) { int i, j; for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { unsigned char gray = image[width*i + j].red; if (gray < 128) { image[width*i + j].red = 0; image[width*i + j].green = 0; image[width*i + j].blue = 0; } else { image[width*i + j].red = 255; image[width*i + j].green = 255; image[width*i + j].blue = 255; } } } } void dilate(RGB* image, int width, int height) { int i, j, k, l, m, n; RGB* temp = (RGB*)malloc(width*height * sizeof(RGB)); if (!temp) { printf("Memory allocation failed\n"); exit(1); } memcpy(temp, image, width*height * sizeof(RGB)); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { int flag = 1; for (k = -1; k <= 1; k++) { for (l = -1; l <= 1; l++) { m = i + k; n = j + l; if (m >= 0 && m < height && n >= 0 && n < width) { if (temp[width*m + n].red == 0) { flag = 0; break; } } } if (!flag) { break; } } if (flag) { image[width*i + j].red = 0; image[width*i + j].green = 0; image[width*i + j].blue = 0; } } } free(temp); } void erode(RGB* image, int width, int height) { int i, j, k, l, m, n; RGB* temp = (RGB*)malloc(width*height * sizeof(RGB)); if (!temp) { printf("Memory allocation failed\n"); exit(1); } memcpy(temp, image, width*height * sizeof(RGB)); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { int flag = 1; for (k = -1; k <= 1; k++) { for (l = -1; l <= 1; l++) { m = i + k; n = j + l; if (m >= 0 && m < height && n >= 0 && n < width) { if (temp[width*m + n].red == 255) { flag = 0; break; } } } if (!flag) { break; } } if (flag) { image[width*i + j].red = 255; image[width*i + j].green = 255; image[width*i + j].blue = 255; } } } free(temp); } void edgeDetection(RGB* image, int width, int height) { int i, j, k, l, m, n; RGB* temp = (RGB*)malloc(width*height * sizeof(RGB)); if (!temp) { printf("Memory allocation failed\n"); exit(1); } memcpy(temp, image, width*height * sizeof(RGB)); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { int flag = 0; for (k = -1; k <= 1; k++) { for (l = -1; l <= 1; l++) { m = i + k; n = j + l; if (m >= 0 && m < height && n >= 0 && n < width) { if (temp[width*m + n].red == 0) { int diff = abs(k) + abs(l); if (diff == 1 || diff == 2) { flag = 1; break; } } } } if (flag) { break; } } if (flag) { image[width*i + j].red = 0; image[width*i + j].green = 0; image[width*i + j].blue = 0; } else { image[width*i + j].red = 255; image[width*i + j].green = 255; image[width*i + j].blue = 255; } } } free(temp); } int main() { RGB* image; int width, height; readBmp("/Users/dezhiwoxing/Desktop/3.bmp", &image, &width, &height); // Image processing gray(image, width, height); binarize(image, width, height); dilate(image, width, height); erode(image, width, height); edgeDetection(image, width, height); saveBmp("/Users/dezhiwoxing/Desktop/result.bmp", image, width, height); free(image); return 0; }本回答被题主选为最佳回答 , 对您是否有帮助呢?评论 打赏 举报 编辑记录解决 2无用