数字图像处理 实验一 位图文件信息的提取和二值化处理

MinGW的配置就不提了

  • 创建四个文件如下,已加入部分注释

hdr.c

#include <stdio.h>
#include <memory.h>
#include "hdr.h"

struct bmphdr *get_header(char filename[])
{
	FILE *fp;
	struct bmphdr *hdr;
  		
	fp = fopen(filename, "rb");
	if (!fp) {
		printf("File open error or such file does not exist!\n");
		return NULL;	
	}
	
	hdr = (struct bmphdr *)malloc(sizeof(struct bmphdr));//分配空间
	fread(hdr->signature, 2, 1, fp);
	if (hdr->signature[0] != 'B' || hdr->signature[1] != 'M') {//如果打开文件的扩展名不是.bmp
		printf("Not a bmp file!\n");
		return NULL;
	}
	//读位图头文件信息
	fread(&hdr->size, 4, 1, fp);
	fread(hdr->reserved, 4, 1, fp);
	fread(&hdr->offset, 4, 1, fp);
	fread(&hdr->hdr_size, 4, 1, fp);
	fread(&hdr->width, 4, 1, fp);
	fread(&hdr->height, 4, 1, fp);
	fread(&hdr->nr_planes, 2, 1, fp);
	fread(&hdr->bits_per_pixel, 2, 1, fp);
	fread(&hdr->compress_type, 4, 1, fp);
	fread(&hdr->data_size, 4, 1, fp);
	fread(&hdr->resol_hori, 4, 1, fp);
	fread(&hdr->resol_vert, 4, 1, fp);
	fread(&hdr->nr_colors, 4, 1, fp);
	fread(&hdr->important_color, 4, 1, fp);
  if (hdr->offset > 54)//获得位图有效信息,偏移量为54的时候读的才是位图第一个像素
		  fread(&hdr->info, 1024, 1, fp);	
  
  fclose(fp);//关闭文件
	return hdr;	
}

hdr.h

#ifndef __HDR_H__
#define __HDR_H__

struct bmphdr {
	char signature[2];//文件类型
	int size;//位图大小
	short reserved[2];//两个保留字
	int offset;//位图偏移位置
	int hdr_size;//头文件大小
	int width;//位图宽度
	int height;//位图高度
	short nr_planes;//位平面数
	short bits_per_pixel;//每像素的位数
	int compress_type;//压缩类型
	int data_size;//数据大小
	int resol_hori;//水平
	int resol_vert;//垂直
	int nr_colors;
	int important_color;
	char info[1024];
};

struct bmphdr *get_header(char filename[]);//获取位图头文件信息

#endif

bmphdr.c

#include <stdio.h>

struct bmphdr {
	char signature[2];//文件类型
	int size;//位图大小
	short reserved[2];//两个保留字
	int offset;//位图偏移位置
	int hdr_size;//头文件大小
	int width;//位图宽度
	int height;//位图高度
	short nr_planes;//位平面数
	short bits_per_pixel;//每像素的位数
	int compress_type;//压缩类型
	int data_size;//数据大小
	int resol_hori;//水平
	int resol_vert;//垂直
	int nr_colors;
	int important_color;
} header;

int main(int argc, char *argv[])
{
	FILE *fp;
	
	if (argc != 2) {
		printf("Usage: %s <filename>\n", argv[0]);
		exit(1);
	}
	
	fp = fopen(argv[1], "r");
	if (!fp) {
		printf("File open error or such file does not exist!\n");
		exit(1);	
	}
	
	fread(header.signature, 2, 1, fp);
	if (header.signature[0] != 'B' || header.signature[1] != 'M') {
		printf("Not a bmp file!\n");
		exit(1);
	}
	//均为位图头信息
	fread(&header.size, 4, 1, fp);//图像大小
	fread(header.reserved, 4, 1, fp);
	fread(&header.offset, 4, 1, fp);//偏移量
	fread(&header.hdr_size, 4, 1, fp);//图像信息头大小,识别不同版本bmp文件
	fread(&header.width, 4, 1, fp);//图像宽度
	fread(&header.height, 4, 1, fp);//图像高度
	fread(&header.nr_planes, 2, 1, fp);
	fread(&header.bits_per_pixel, 2, 1, fp);
	fread(&header.compress_type, 4, 1, fp);
	fread(&header.data_size, 4, 1, fp);
	fread(&header.resol_hori, 4, 1, fp);
	fread(&header.resol_vert, 4, 1, fp);
	fread(&header.nr_colors, 4, 1, fp);
	fread(&header.important_color, 4, 1, fp);

	fclose(fp);
	printf("signature        %c%c\n", header.signature[0], header.signature[1]);
	printf("size             %d\n", header.size);
	printf("offset           %d\n", header.offset);
	printf("hdr_size         %d\n", header.hdr_size);
	printf("width            %d\n", header.width);
	printf("height           %d\n", header.height);
	printf("nr_planes        %d\n", header.nr_planes);
	printf("bits_per_pixel   %d\n", header.bits_per_pixel);
	printf("compress_type    %d\n", header.compress_type);
	printf("data_size        %d\n", header.data_size);
	printf("resol_hori       %d\n", header.resol_hori);
	printf("resol_vert       %d\n", header.resol_vert);
	printf("nr_colors        %d\n", header.nr_colors);
	printf("important_color  %d\n", header.important_color);
	printf("\n");
	return 0;	
}

ez.c

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "hdr.h"

struct bmphdr *hdr;
unsigned char *bitmap, *to;
char buf[2048];

int main(int argc, char *argv[])
{
	int i, j, k, nr_pixels;
 	FILE *fp, *fpnew;	
	unsigned g;
	
	if (argc != 4) {
		printf("Usage: %s <file_from> <file_to> <threshold>\n", argv[0]);
		exit(1);
	}
	
	hdr = get_header(argv[1]);

	if (!hdr) exit(1);

	fp = fopen(argv[1], "rb");//打开位图文件
	
	if (!fp) {//如果打开错误,给出提示
		printf("File open error!\n");
		exit(1);
	}

	fseek(fp, hdr->offset, SEEK_SET);
	nr_pixels = hdr->width * hdr->height;
	bitmap = malloc(nr_pixels);
	fread(bitmap, nr_pixels, 1, fp);
	fclose(fp);

	k  = atoi(argv[3]);
	to = malloc(nr_pixels);
	memset(to, 0, nr_pixels);
	for (i = 0; i < nr_pixels; i++)
	  to[i] = bitmap[i] > (unsigned char)k ? 255 : 0;
	
	fpnew = fopen(argv[2], "wb+");
	
	if (!fpnew) {
		printf("File create error!\n");
		exit(1);
	}
	//位图头信息
	fwrite(hdr->signature, 2, 1, fpnew);
	fwrite(&hdr->size, 4, 1, fpnew);
	fwrite(hdr->reserved, 4, 1, fpnew);
	fwrite(&hdr->offset, 4, 1, fpnew);
	fwrite(&hdr->hdr_size, 4, 1, fpnew);
	fwrite(&hdr->width, 4, 1, fpnew);
	fwrite(&hdr->height, 4, 1, fpnew);
	fwrite(&hdr->nr_planes, 2, 1, fpnew);
	fwrite(&hdr->bits_per_pixel, 2, 1, fpnew);
	fwrite(&hdr->compress_type, 4, 1, fpnew);
	fwrite(&hdr->data_size, 4, 1, fpnew);
	fwrite(&hdr->resol_hori, 4, 1, fpnew);
	fwrite(&hdr->resol_vert, 4, 1, fpnew);
	fwrite(&hdr->nr_colors, 4, 1, fpnew);
	fwrite(&hdr->important_color, 4, 1, fpnew);
	if (hdr->offset > 54)
		fwrite(hdr->info, hdr->offset - 54, 1, fpnew);
	fwrite(to, nr_pixels, 1, fpnew);
	
	fclose(fpnew);
	free(hdr);
	free(bitmap);

	return 0;
}

然后,在控制台下分别使用

gcc -c hdr.c
gcc -c bmphdr.c
gcc -c ez.c
gcc -o ez.exe ez.c hdr.c

编译链接出ez.exe程序,在控制台下使用ez.exe 输入文件 输出文件 阈值即可输出二值化之后的图片,阈值可选108

  • 这个实验的大致目的就是给你一张图片,然后你需要把它变成黑白图,如下所示

原图在这里插入图片描述
二值化后在这里插入图片描述

  • 上面的程序不难理解,这里提一下main函数的参数问题,argc表示参数个数,数组argv存储参数,如果不传参,默认第一个参数为程序名,也就是说argv是从1开始的,可以写程序在控制台测试一下看看
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clarence Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值