图像信息处理实验二

要求:

1. Image binarization
2. Binary image erosion
3. Binary image delation
4. Binary image opening
5. Binary image closing

#include <stdio.h>
#include <Windows.h>


void ToRGB(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图文件头
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开位图失败\n");
		exit(-1);
	}

	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);  //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);  //读取信息头
	WORD bitCount = infoHeader.biBitCount;  //颜色位数
	if (bitCount == 16)
	{
		exit(-1);
	}
	int Clr = 0;

	RGBQUAD *QUAD = NULL;
	if (bitCount < 16)
	{

		Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount;
		if (Clr>256)
			Clr = 0;
	}
	// 读取调色板
	int i = 0, j = 0;
	if (Clr > 0)
	{
		QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr);
		fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile);
		for (i = 0; i < Clr; i++)
		{
			QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen =
				(BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue);
		}
	}
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

    int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据
	if (Clr == 0)
	{
		for (i = 0; i < pH; i++)//行
		{
			if (bitCount == 24)
			{
				for (j = 0; j < pW * 3; j = j + 3)// 列,因为每个像素占3个字节
                {
					int n = i*LineSize + j;
					int r = P[n];
					int g = P[n+1];
					int b = P[n + 2];

					int y = 0.299*r + 0.587*g + 0.114*b;
					int u = 0.492*(b - y);
					int v = 0.877*(r - y);
					y = y + 31;  //把所有像素点的y增大31
					/*if (y > 255)  //如果越界则置为255
						y = 255;
					if (y < 0)
						y = 0;
					if (u > 255)  //如果越界则置为255
						u = 255;
					if (u < 0)
						u = 0;
					if (v > 255)  //如果越界则置为255
						v = 255;
					if (v < 0)
						v = 0; */
					int R = y + 1.14*v;
					int G = y -0.394*u - 0.581*v;
					int B = y + 2.032*u;

					if (R > 255)  //R如果越界则置为255
						R = 255;
					if (R < 0)
						R = 0;
					if (G > 255)  //如果越界则置为255
						G = 255;
					if (G < 0)
						G = 0;
					if (B > 255)  //如果越界则置为255
						B = 255;
					if (B < 0)
						B = 0;
					P[n]  = (BYTE)(R); //分别是新r.g.b分量
					P[n + 1] = (BYTE)(G);
					P[n + 2] = (BYTE)(B);
				}
			}

		}
	}
	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P=NULL;
	}
}

void ToGrey(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数
	if (bitCount == 16)
	{
		exit(-1);
	}
	int Clr = 0;

	RGBQUAD *QUAD = NULL;
	if (bitCount < 16)
	{

		Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount;
		if (Clr>256)
			Clr = 0;
	}
	// 读取调色板
	int i = 0, j = 0;
	if (Clr > 0)
	{
		QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr);
		fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile);
		for (i = 0; i < Clr; i++)
		{
			QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen =
				(BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue);  //灰度图像三个都是y
		}
	}
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据

    for(i = 0; i < pH; i++)//行
    {


			for (j = 0; j < pW*3; j = j + 3)// 列
			{
                int n = i*LineSize + j;
                if(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]>120)
                    P[n] = P[n + 1] = P[n + 2] = (BYTE)255;
                else
                    P[n] = P[n + 1] = P[n + 2] = (BYTE)0;

			}


	}

	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}

void Delation(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数

	int Clr = 0;

	RGBQUAD *QUAD = NULL;

	int i = 0, j = 0;
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据

    //先二值化
    for(i = 0; i < pH; i++)//行
    {
		for (j = 0; j < pW*3; j = j + 3)// 列
		{
            int n = i*LineSize + j;
            if(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]>120)
                P[n] = P[n + 1] = P[n + 2] = (BYTE)255;
            else
                P[n] = P[n + 1] = P[n + 2] = (BYTE)0;


		}
	}
    //再delation
    int width=3,height=3;
    int mid=(width+1)/2-1;
    int p,q;
    int n;
    BYTE v = 255;
    for(i = mid; i < pH - mid; i++)//行
    {
        for (j = mid; j < (pW-mid) * 3; j = j + 3)// 列
		{
		    for(p = 0; p < height; p++)
            {
                for(q = 0; q < width * 3; q = q + 3)
                {
                    if(p == mid && q == mid) continue;
                    n=(i+p)*LineSize + (j+q);
                    v &= P[n];
                }
		    }
		    n = i * LineSize + j;
		    P[n] = P[n + 1] = P[n + 2] = v;
		    v = 255;
		}
	}

	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}

void Erosion(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");

	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数

	int Clr = 0;

	RGBQUAD *QUAD = NULL;

	int i = 0, j = 0;

	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据

    //先二值化
    for(i = 0; i < pH; i++)//行
    {
		for (j = 0; j < pW*3; j = j + 3)// 列
		{
            int n = i*LineSize + j;
            if(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]>120)
                P[n] = P[n + 1] = P[n + 2] = (BYTE)255;
            else
                P[n] = P[n + 1] = P[n + 2] = (BYTE)0;


		}
	}
    //再erosion
    int width=3,height=3;
    int mid=(width+1)/2-1;
    int p,q;
    int n;
    BYTE v = 0;
    for(i = mid; i < pH - mid; i++)//行
    {
        for (j = mid; j < (pW-mid) * 3; j = j + 3)// 列
		{
		    for(p = 0; p < height; p++)
            {
                for(q = 0; q < width * 3; q = q + 3)
                {
                    if(p == mid && q == mid) continue;
                    n=(i+p)*LineSize + (j+q);
                    v |= P[n];
                }
		    }
		    n = i * LineSize + j;
		    P[n] = P[n + 1] = P[n + 2] = v;
		    v = 0;
		}
	}

	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}

void Opening(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");

	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数

	int Clr = 0;

	RGBQUAD *QUAD = NULL;

	int i = 0, j = 0;

	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据

    //先二值化
    for(i = 0; i < pH; i++)//行
    {
		for (j = 0; j < pW*3; j = j + 3)// 列
		{
            int n = i*LineSize + j;
            if(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]>120)
                P[n] = P[n + 1] = P[n + 2] = (BYTE)255;
            else
                P[n] = P[n + 1] = P[n + 2] = (BYTE)0;


		}
	}
    //再erosion
    int width=3,height=3;
    int mid=(width+1)/2-1;
    int p,q;
    int n;
    BYTE v = 0;
    for(i = mid; i < pH - mid; i++)//行
    {
        for (j = mid; j < (pW-mid) * 3; j = j + 3)// 列
		{
		    for(p = 0; p < height; p++)
            {
                for(q = 0; q < width * 3; q = q + 3)
                {
                    if(p == mid && q == mid) continue;
                    n=(i+p)*LineSize + (j+q);
                    v |= P[n];
                }
		    }
		    n = i * LineSize + j;
		    P[n] = P[n + 1] = P[n + 2] = v;
		    v = 0;
		}
	}
    //再Delation
    v = 255;
    for(i = mid; i < pH - mid; i++)//行
    {
        for (j = mid; j < (pW-mid) * 3; j = j + 3)// 列
		{
		    for(p = 0; p < height; p++)
            {
                for(q = 0; q < width * 3; q = q + 3)
                {
                    if(p == mid && q == mid) continue;
                    n=(i+p)*LineSize + (j+q);
                    v &= P[n];
                }
		    }
		    n = i * LineSize + j;
		    P[n] = P[n + 1] = P[n + 2] = v;
		    v = 255;
		}
	}

	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}

void Closing(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");

	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数

	int Clr = 0;

	RGBQUAD *QUAD = NULL;

	int i = 0, j = 0;

	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据

    //先二值化
    for(i = 0; i < pH; i++)//行
    {
		for (j = 0; j < pW*3; j = j + 3)// 列
		{
            int n = i*LineSize + j;
            if(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]>120)
                P[n] = P[n + 1] = P[n + 2] = (BYTE)255;
            else
                P[n] = P[n + 1] = P[n + 2] = (BYTE)0;


		}
	}
	//先Delation
	int width=3,height=3;
    int mid=(width+1)/2-1;
    int p,q;
    int n;
	BYTE v = 255;
    for(i = mid; i < pH - mid; i++)//行
    {
        for (j = mid; j < (pW-mid) * 3; j = j + 3)// 列
		{
		    for(p = 0; p < height; p++)
            {
                for(q = 0; q < width * 3; q = q + 3)
                {
                    if(p == mid && q == mid) continue;
                    n=(i+p)*LineSize + (j+q);
                    v &= P[n];
                }
		    }
		    n = i * LineSize + j;
		    P[n] = P[n + 1] = P[n + 2] = v;
		    v = 255;
		}
	}
    //再erosion

    v = 0;
    for(i = mid; i < pH - mid; i++)//行
    {
        for (j = mid; j < (pW-mid) * 3; j = j + 3)// 列
		{
		    for(p = 0; p < height; p++)
            {
                for(q = 0; q < width * 3; q = q + 3)
                {
                    if(p == mid && q == mid) continue;
                    n=(i+p)*LineSize + (j+q);
                    v |= P[n];
                }
		    }
		    n = i * LineSize + j;
		    P[n] = P[n + 1] = P[n + 2] = v;
		    v = 0;
		}
	}

	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);

	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}


int main()
{

	ToGrey("d.bmp", "grayd.bmp");
	ToRGB("d.bmp", "rgbd.bmp");
	Erosion("d.bmp", "erosiond.bmp");
	Delation("d.bmp","delationd.bmp");
	Opening("d.bmp","opend.bmp");
	Closing("d.bmp","closed.bmp");
	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水木流年追梦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值