图像的缩小(c++实现)

图像的缩小(c++实现)

图像的缩小(或称为下采样、降采样)是指在通过对像素点的映射,以达到缩小图片分辨率的操作,最核心的一点就是设置一个缩放比例,按比例找到相应的映射即可。
matlab代码如下:

%Image为原图像,m,n为原图像宽高,New为缩小后的图像
M = 0.5;    %缩小倍数
m1=m*M;n1=n*M;
for i=1:m1
    for j=1:n1;
        New(i,j)=Image(round(i/M),round(j/M));
    end
end

c++实现代码如下:

#include <string.h>   
#include <math.h>        
#include <stdlib.h>     
#include <malloc.h>  
#include <iostream>
using namespace std;
#include<time.h>//时间相关头文件,可用其中函数计算图像处理速度  
using namespace std;

#define   WIDTHBYTES(bits) (((bits)+31)/32*4)//用于使图像宽度所占字节数为4byte的倍数  

typedef unsigned char  BYTE;  
typedef unsigned short WORD;  
typedef unsigned long  DWORD; //win32,win64,lin32改为long(4字节),linux64 long下为8字节
typedef int LONG;  
  
//位图文件头信息结构定义  
//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)  
typedef struct tagBITMAPFILEHEADER {  
DWORD  bfSize;          //文件大小  
WORD   bfReserved1;     //保留字,不考虑  
WORD   bfReserved2;     //保留字,同上  
DWORD  bfOffBits;       //实际位图数据的偏移字节数,即前三个部分长度之和  
} BITMAPFILEHEADER;   
  
//信息头BITMAPINFOHEADER,也是一个结构,其定义如下:  
  
typedef struct tagBITMAPINFOHEADER{  
//public:  
DWORD   biSize;             //指定此结构体的长度,为40  
LONG    biWidth;            //位图宽  
LONG    biHeight;           //位图高  
WORD    biPlanes;           //平面数,为1  
WORD    biBitCount;         //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32  
DWORD   biCompression;      //压缩方式,可以是0,1,2,其中0表示不压缩  
DWORD   biSizeImage;        //实际位图数据占用的字节数  
LONG    biXPelsPerMeter;    //X方向分辨率  
LONG    biYPelsPerMeter;    //Y方向分辨率  
DWORD   biClrUsed;          //使用的颜色数,如果为0,则表示默认值(2^颜色位数)  
DWORD   biClrImportant;     //重要颜色数,如果为0,则表示所有颜色都是重要的  
} BITMAPINFOHEADER;   
int main()
{
    float now=0;
	now=clock();//存储图像处理开始时间
 
	BITMAPFILEHEADER bitHead;
	BITMAPINFOHEADER bitInfoHead; 
	FILE* pfile = NULL;
	FILE* wfile = NULL;
 
	char strFile[100]="/home/lzm/1/test_img/lena24.bmp";//打开图像路径,需修改为自己图像存储的路径
	char strFilesave[100]="./05.bmp";//处理后图像存储路径,需修改为自己图像存储的路径
	pfile = fopen(strFile,"rb");//文件打开图像
	wfile = fopen(strFilesave,"wb");//打开文件为存储修改后图像做准备
    
	//读取位图文件头信息
	WORD fileType;
	fread(&fileType,1,sizeof(WORD),pfile);
	fwrite(&fileType,1,sizeof(WORD),wfile);
	if(fileType != 0x4d42)
	{
		printf("file is not .bmp file!");
		return 0;
	}
	fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),pfile);
	fwrite(&bitHead,1,sizeof(tagBITMAPFILEHEADER),wfile);//写回位图文件头信息到输出文件  
    
	//读取位图信息头信息
	fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile);
	fwrite(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),wfile);//写回位图信息头信息到输出文件  
 
	int width = bitInfoHead.biWidth;
	int height = bitInfoHead.biHeight;
	printf("%d %d\n",bitInfoHead.biWidth,bitInfoHead.biHeight);
	//分配内存空间把源图存入内存   
	int l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为4byte的倍数 
	printf("%d\n",bitInfoHead.biBitCount);
	printf("%d\n",l_width);
	BYTE    *pColorData=(BYTE *)malloc(height*l_width);//开辟内存空间存储图像数据
	memset(pColorData,0,height*l_width);   
	BYTE    *pColorDataMid=(BYTE *)malloc(height*l_width);//开辟内存空间存储图像处理之后数据
	memset(pColorDataMid,0,height*l_width); 
 
	LONG nData = height*l_width;
    int rateN=0.5  //定义缩小比例
	//把位图数据信息读到数组里   
	fread(pColorData,1,nData,pfile);//图像处理可通过操作这部分数据加以实现,可将下面的示例修改为中值滤波等各种图像处理模块
									//在嵌入式开发环境下,大多数情况下已经得到图像数据区,是故将下面部分代码稍作修改就可以移植到嵌入式端
	/*******************图像处理部分******************/
		for(int hnum=0;hnum<(int)height*rateN;hnum++)
			for(int wnum=0;wnum<(int)width*rateN;wnum++)
			{
                int pixel_point=hnum*l_width+wnum*3;//数组位置偏移量,对应于图像的各像素点RGB的起点
				pColorDataMid[pixel_point]=pColorData[(int)pixel_point/rateN]*0.5;
				pColorDataMid[pixel_point+1]=pColorData[(int)pixel_point/rateN+1]*0.5;
				pColorDataMid[pixel_point+2]=pColorData[(int)pixel_point/rateN+2]*0.5;
			}
	/*******************图像处理部分******************/
	fwrite(pColorDataMid,1,nData,wfile);//将处理完图像数据写回文件
	fclose(pfile);
	fclose(wfile);
	//printf("图像处理完成\n");pd
	//printf("运行时间为:%.2fms\n",(clock()-now)/1000);//输出图像处理花费时间信息
	cout<<"图像处理完成\n";
	cout<<"运行时间为:"<<(clock()-now)/1000<<"ms\n";
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值