引言:
从摄像头和传感器获得的视频数据是没有办法直接被电脑识别的,所以需要进行转化,我昨天在做项目的时候遇到了这个问题,根据查阅相关资料,实现了将摄像头输出的原始数据文件转换成bmp图像的程序。
语言:
C/C++
测试平台:
VC6.0
先把bmp.h头文件贴出来:
#ifndef __BMP_H__
#define __BMP_H__
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned long LONG;
typedef struct tagBITMAPFILEHEADER { // bmfh
WORD bfType; // 文件标识‘BM’
DWORD bfSize; // 用字节表示的整个文件的大小
WORD bfReserved1; // 保留字节,为0
WORD bfReserved2; // 保留字节,为0
DWORD bfOffBits; // 图象数据RGBA的起始地址的偏移值 为54
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{ // bmih
DWORD biSize; // 位图信息头(Bitmap Info Header)的长度,为40
LONG biWidth; // 位图的宽度,以象素为单位
LONG biHeight; // 位图的高度,以象素为单位
WORD biPlanes; // 位图的位面数(注:该值将总是1)
WORD biBitCount; // 每个象素的位数,设为24(表示24Bit位图)
DWORD biCompression; // 压缩说明,设为0(不压缩)
DWORD biSizeImage; // 用字节数表示的位图数据的大小(该数必须是4的倍数)
LONG biXPelsPerMeter; // 用象素/米表示的水平分辨率(一般设为0)
LONG biYPelsPerMeter; // 用象素/米表示的垂直分辨率(一般设为0)
DWORD biClrUsed; // 位图使用的颜色数(一般设为0)
DWORD biClrImportant; // 指定重要的颜色数(一般设为0)
} BITMAPINFOHEADER;
#endif
下面就是实现代码:
注意:本人一般喜欢把指针用得很逆天,心脏不好的朋友就别往下读了
#include
#include
#include "bmp.h"
#define WIDTH(640)
#define HEIGHT(512)
#define IMAGESIZE16 ((WIDTH)*(HEIGHT)*2)
#defineIMAGESIZE24((IMAGESIZE16/2)*3)
#define _DEBUG_ printf("-----------\n");
void pixel_rgb565_to_rgb24(const unsigned char *p16,unsigned char *p24)//将16bit的像素转化为24bit的像素
{
unsigned char R,G,B;
B=*(unsigned short*)p16 & 0x01F;
G=(*(unsigned short*)p16 & 0x7E0) >> 5;
R=(*(unsigned short*)p16 >> 11 ) & 0x1F;
*(p24+0)=B << 2; // 把5bits映射到8bits去,自己可以优化一下算法,下同
*(p24+1)=G << 1;
*(p24+2)=R << 2;
}
void image16_to_image24(const unsigned char *image16, unsigned char *image24, int biWidth, int biHeight)
{
const unsigned char *p16 = image16;
unsigned char *p24 = image24;
int i;
for(i=0; i
{
pixel_rgb565_to_rgb24(p16, p24);
}
}
void main()
{
//BITMAPFILEHEADER bmp_fileheader;
unsigned char bmp_fileheader[14];//位图文件头
BITMAPINFOHEADER bmp_infoheader;//位图信息头
//位图文件头
//因为字节对齐的问题,所以位图文件头用数组来定义
*(WORD *)bmp_fileheader = 'B' | 'M' << 8;//bfType 文件标识'BM'
*(DWORD *)(bmp_fileheader + 2) = 14 + 40 + IMAGESIZE24;//bfSize 文件的大小
*(DWORD *)(bmp_fileheader + 6) = 0; //bfReserved1 和 bfReserved2
*(DWORD *)(bmp_fileheader + 10) = 54;//bfOffBits 图象数据RGBA的起始地址的偏移值 为54
//位图信息头
bmp_infoheader.biSize = 40;
bmp_infoheader.biWidth = WIDTH;//图像width
bmp_infoheader.biHeight = HEIGHT;//图像height
bmp_infoheader.biPlanes = 1;
bmp_infoheader.biBitCount = 24;//像素精度
bmp_infoheader.biCompression = 0;
bmp_infoheader.biSizeImage = IMAGESIZE24;//图像大小
bmp_infoheader.biXPelsPerMeter = 0;
bmp_infoheader.biYPelsPerMeter = 0;
bmp_infoheader.biClrUsed = 0;
bmp_infoheader.biClrImportant = 0;
unsigned char *imagedata16 = new unsigned char[IMAGESIZE16];
unsigned char *imagedata24 = new unsigned char[IMAGESIZE24];
FILE *image = fopen("D:\\image.original", "rb");
fread(imagedata16, IMAGESIZE16, 1, image);
fclose(image);
image16_to_image24(imagedata16, imagedata24, 640, 512);
FILE *file = fopen("D:\\ynd.bmp", "ab");
fwrite(bmp_fileheader, 14, 1, file);
fwrite(&bmp_infoheader, 40, 1, file);
fwrite(imagedata24, IMAGESIZE24, 1, file);
fclose(file);
delete []imagedata16;
delete []imagedata24;
}
程序运行后会将D:\image.original(原始图像,16位RGB565格式)转化成电脑软件能识别的24位ynd.bmp
好吧