图像的缩小(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";
}