首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

bmp图像处理的。有关问题不难,小弟我初学,请多指点

2012-05-20 
bmp图像处理的。问题不难,我初学,请多指点。[codeC/C++][/code]#includestdlib.h#include ctype.h#incl

bmp图像处理的。问题不难,我初学,请多指点。
 

[code=C/C++][/code]
#include<stdlib.h>

#include <ctype.h>  
#include <malloc.h>  

#include"Similarity.h"
#include"huiduxst.h"

#define WIDTHBYTES(i) ((i+31)/32*4)  
 
int main()  
{  
  BITMAPFILEHEADER bf; //BMP文件头结构体  
  BITMAPINFOHEADER bi; //BMP信息头结构体  
   
  FILE* fp; //指向文件的指针  
   
  DWORD LineByte,ImgSize;  
 
  DWORD NumColors;  
  unsigned char * * Imgdata;
unsigned char * * Smlryimadata;  
  int i,j;  
   
  unsigned char pix[3];  
   
  fp=fopen("景甜.bmp","rb");  
  if(fp == NULL){  
  printf("Open file error!");  
  exit(0);  
  }  
  
  //读取信息头、文件头  
  fread(&bf,sizeof(BITMAPFILEHEADER),1,fp); //把指针fp所指向的文件的头信息写入bf(地址)  
  fread(&bi,sizeof(BITMAPINFOHEADER),1,fp);  
  
  
  LineByte=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount); //计算位图的实际宽度并确保它为32的倍数  
  ImgSize=(DWORD)LineByte*bi.biHeight;  
  
if (bi.biClrUsed != 0 )  
  NumColors=(DWORD)bi.biClrUsed;  
else  
  switch (bi.biBitCount)  
  {  
  case 1:NumColors=2;break;  
  case 4:NumColors=16;break;  
  case 8:NumColors=256;break;  
  case 24:NumColors=0;break;  
  }  
//分配调色板内存  
 
  
Imgdata=new unsigned char*[bi.biHeight]; //声明一个指针数组  

   
  
  for ( i=(bi.biHeight)-1;i>=0;i--)  
  Imgdata[i]=new unsigned char[bi.biWidth*3]; //每个数组元素也是一个指针数组  
  
  for ( i=(bi.biHeight)-1;i>=0;i--)  
  for(j=0;j<bi.biWidth*3;j++)  
  fread(&Imgdata[i][j],1,1,fp);//每次只读取一个1字节,存入数组  


//-------------------------Skin color similarity image----------------------//
Smlryimadata =new unsigned char*[bi.biHeight];

for ( i=(bi.biHeight)-1;i>=0;i--)  
  Smlryimadata[i]=new unsigned char[bi.biWidth];

for (i = (bi.biHeight) - 1;i >=0;i--)
  for(j=0;j<bi.biWidth;j++){ 
pix[0]=Imgdata[i][3*j+0];
  pix[1]=Imgdata[i][3*j+1];
pix[2]=Imgdata[i][3*j+2];
Smlryimadata[i][j] = (unsigned char)Similarity(pix); //调试的时候 观察;  
  }
  //Smlryimadata[i][j]的值
  FILE *fp1;
  fp1=fopen("Smlryimadata.txt","wb"); //与接下来写入Smlryimadata.txt后
  for(i=0;i<bi.biHeight;i++)
for(j=0;j<bi.biWidth;j++) //打开后发现与原先观察的结果不同;
{
//fwrite(&Smlryimadata[i][j],1,1,fp1); //不知道为什么用fwrite(&Smlryimadata[i]  
fprintf(fp1,"%d\n",Smlryimadata[i][j]); //[j],1,1,fp1);写入后打开是乱码? 
}
  //fwrite(&Smlryimadata[0][0],1,1,fp1);
  //fprintf(fp1,"%d\n",Smlryimadata[0][1]);
  fclose(fp1);
   
huiduxst(Smlryimadata,bi.biWidth,bi.biHeight);
free(Smlryimadata); 


free(Imgdata);  
fclose(fp);  

return 0;  
  
}


[code=C/C++][/code]
//这个函数是要将数据写入到8位的bmp文件中去,可是写入后的文件后打开总是空。而且格式和属性都与文件头信息头设定的
// 不同!
#include"huiduxst.h"

typedef unsigned long DWORD;
//typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef long LONG;
#define BI_RGB 0L


void huiduxst(unsigned char **Imgdata, long biWidth,long biHeight){
   
  FILE * fp;  
  BITMAPFILEHEADER targetfileheader;
  BITMAPINFOHEADER targetinfoheader;
  memset(&targetfileheader,0,sizeof(BITMAPFILEHEADER));
  memset(&targetinfoheader,0,sizeof(BITMAPINFOHEADER)); 

  //构造灰度图的文件头
  targetfileheader.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256; 
  targetfileheader.bfSize=biWidth*biHeight+sizeof(RGBQUAD)*256 +sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);  
  targetfileheader.bfReserved1=0;
  targetfileheader.bfReserved2=0;
  targetfileheader.bfType=0x4d42;


  //构造灰度图的信息头
  targetinfoheader.biBitCount=8;
  targetinfoheader.biSize=sizeof(BITMAPINFOHEADER);
  targetinfoheader.biHeight=biHeight;
  targetinfoheader.biWidth=biWidth;
  targetinfoheader.biPlanes=1;
  targetinfoheader.biCompression=BI_RGB;
  targetinfoheader.biSizeImage=0;
  targetinfoheader.biXPelsPerMeter=0;
  targetinfoheader.biYPelsPerMeter=0;
  targetinfoheader.biClrImportant=0;
  targetinfoheader.biClrUsed=0;

  //构造灰度图的调色版

  RGBQUAD rgbquad[256];
  int i,j;
FILE *fp1=fopen("灰度.txt","wb");
  fwrite(*Imgdata,1,biWidth*biHeight,fp1);  
  fclose(fp1);

for(i=0;i<256;i++)
  {
  rgbquad[i].rgbBlue=i;
  rgbquad[i].rgbGreen=i;
  rgbquad[i].rgbRed=i;
  rgbquad[i].rgbReserved=0;
  } 
//fclose(fopen("灰度图.bmp","w"));
  fp=fopen("灰度图.bmp","wb");  
  fwrite(rgbquad,sizeof(RGBQUAD),256,fp);  

fwrite(&targetfileheader,sizeof(BITMAPFILEHEADER),1,fp);  
fwrite(&targetinfoheader,sizeof(BITMAPINFOHEADER),1,fp);  
  
 
  fwrite(rgbquad,sizeof(RGBQUAD),256,fp);  
  
  for (i=targetinfoheader.biHeight-1;i>=0;i--)  
  for (j=0 ;j<targetinfoheader.biWidth;j++) {  
  // Imgdata[i][j] = 255 - Imgdata[i][j];  
  fwrite(&Imgdata[i][j],1,1,fp);  
  fclose(fp);
  }  
}  

[code=C/C++][/code]

#include"Similarity.h"

  double Similarity(unsigned char p[3])
{  
double simirity=0;
double c[3][3]={{0.0009,0.0022,0.0011},{0.0022,0.8209,0.4004},{0.0011,0.4004,0.2117}};
double x[3]={23.6982,121.0278,141.3382};
   
double xx[3];

int i,j;
for(i=0;i<=2;i++)
{
xx[i]=p[i]-x[i];
}
   
double xc[3]={0,0,0};
for (i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
xc[i]+=xx[j]*c[j][i];
}
}

for(i=0;i<=2;i++)
{
simirity+=xc[i]*p[i];
}

  return (255*exp(-0.5*simirity));

}


[code=C/C++][/code]
huiduxst.h:


#ifndef STDIOH
#define STDIOH
#include <stdio.h>
#endif

#include <string.h> 
#include <windows.h> 
void huiduxst(unsigned char **p, long ,long );

[code=C/C++][/code]

Similarity.h:

#include <math.h>  
double Similarity(unsigned char p[3]);


大家好:这是我做人脸识别到时候在提取灰度相似图用到的程序。请大家帮帮忙!问题我在程序终有注释。谢谢!





[解决办法]
乱码先自己调试呗,记录写文件之前的数据,然后对比文件数据,如果不对,就只写一个字节的数据作对比。
[解决办法]
//fwrite(&Smlryimadata[i][j],1,1,fp1);
这样写进去的等于把内存中的东西复制到硬盘中,你当然看不出是什么
而且你写错了,应该这样写:
fwrite(&Smlryimadata[i][j], sizeof(Smlryimadata[i][j]), 1,fp1);
[解决办法]
做图像处理 最好用第三方的库。
不建议用WinAPI做图像处理。毕竟WinAPI是给GUI设计的,很不直观。
[解决办法]
不要把
fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待

fopen("...","...b");fread,fwrite,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待
弄混了

推荐使用WinHex软件查看文件或内存中的原始字节内容。

对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。

热点排行