| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 566 人关注过本帖
标题:二值图像问题
只看楼主 加入收藏
wenzhongyue
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-5-11
结帖率:0
收藏
已结贴  问题点数:20 回复次数:9 
二值图像问题
各位,你们好!我要从黑白的图像中读取它的像素值,但是读出来的值是0~255之间的值,可是我的图像是1位的位图,请问这是什么原因呢?在此先谢谢了!
搜索更多相关主题的帖子: 图像 
2009-08-11 15:20
xufen340
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:166
专家分:1351
注 册:2009-8-7
收藏
得分:20 
贴代码
2009-08-11 16:33
wenzhongyue
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-5-11
收藏
得分:0 
#include <string.h>  
#include <stdio.h>  
#include<math.h>     
#include<stdlib.h>   
#include<malloc.h>
#pragma pack (1)  
 
#define   WIDTHBYTES(bits) (((bits)/8+3)/4*4)
 
/* bitmap file header */  
typedef struct  
{  
    unsigned short  type;  
    unsigned long fileSize;  
    unsigned short reserved1;  
    unsigned short reserved2;  
    unsigned long offbits;  
} BITMAPFILEHEADER;  
 
/* bitmap info header */  
typedef struct   
{  
    unsigned long dwSize;  
    unsigned long biwidth;  
    unsigned long biheight;  
    unsigned short planes;  
    unsigned short  bpp;  
    unsigned long compression;  
    unsigned long sizeImage;  
    unsigned long hResolution;  
    unsigned long vResolution;  
    unsigned long colors;  
    unsigned long importantColors;  
} BITMAPINFOHEADER;
 
typedef struct
{
    unsigned char rgbblue;
    unsigned char rgbgreen;
    unsigned char rgbred;
    unsigned char rgbreserved;
}RGBQUAD;  
 
/*struct bit
{
    unsigned a:1;
};*/
BITMAPFILEHEADER fileHeader;  
BITMAPINFOHEADER infoHeader;     
RGBQUAD   rgbquad[2];
int width;  
int height;
int bpp;
int *pColorData;
int *pColorData1;
void  readbmp()  
{      
    FILE* fp;  
    // char fou[255];     
    int i,j,t=0;
     
    // printf("resultfile name:");  
    //scanf("%s",fou);  
     
    fp=fopen("bw22.bmp","rb");                     //打开图像文件  
    if(fp==NULL)  
    {  
        printf("open file error!\n");  
        exit(0);                                     //?  
    }  
     
    fseek(fp,0,0);  
    fread(&fileHeader,sizeof(fileHeader),1,fp);  
    fseek(fp,sizeof(fileHeader),0);  
    fread(&infoHeader,sizeof(infoHeader),1,fp);      
     
    printf("%d \n  到数据区的偏移量%d \n",fileHeader.type,fileHeader.offbits);  
    printf("信息头长%d \n 宽%d \n 高%d \n %d\n 位数%d \n %d\n 数据区大小%d \n %d \n ",infoHeader.dwSize,infoHeader.biwidth,infoHeader.biheight,infoHeader.planes,infoHeader.bpp, ,infoHeader.sizeImage,infoHeader.colors);
    fseek(fp,sizeof(fileHeader)+sizeof(infoHeader),0);  
    fread(&rgbquad[0],sizeof(RGBQUAD),1,fp);
    printf("索引号0:B-%d G-%d R-%d \n",rgbquad[0].rgbblue,rgbquad[0].rgbgreen,rgbquad[0].rgbred);
    fread(&rgbquad[1],sizeof(RGBQUAD),1,fp);
    printf("索引号1:B-%d G-%d R-%d \n",rgbquad[1].rgbblue,rgbquad[1].rgbgreen,rgbquad[1].rgbred);
    bpp=infoHeader.bpp;
     width = infoHeader.biwidth;
     height = infoHeader.biheight;
    //分配内存空间把源图存入内存   
    int l_width = WIDTHBYTES(width* infoHeader.bpp);//计算位图的实际宽度并确保它为32的倍数
    printf("实际每行字节数%d \n ",l_width);
    pColorData=(int *)malloc(height*l_width);  
    pColorData1=(int*)malloc(height*l_width);  
    memset(pColorData,0,height*l_width);  
     
    long nData = height*l_width;
    unsigned char maxindex=0;
    //把位图数据信息读到数组里
    fseek(fp,fileHeader.offbits,0);
    fread(pColorData,1,nData,fp);
    printf("像素数据信息:\n");
     
    if (infoHeader.bpp==1)
    {  
        for(i=0;i<height;i++)
        {
            for(j=0;j<width;j++)
            {
                maxindex=*(pColorData+i*l_width+j);
                t+=maxindex;
               
                printf("%d ",maxindex);
                                               
               *(pColorData1+i*l_width+j)=maxindex;
            }
            printf("\n");
        }
        t=t/(height*width);
        printf("\n平均%d\n",t);     
    }   
    fclose(fp);
}
 
void savebmp(int *pColorData,int width,int height,int bpp)
{
    FILE *wf;
    wf=fopen("bw2重构.BMP","wb+");                     //打开图像文件  
    int colorTablesize=0;
    if(bpp==1)
        colorTablesize=8;
    int l_width = WIDTHBYTES(width* bpp);
    fileHeader.type = 0x4D42;//bmp类型
    //bfSize是图像文件4个组成部分之和
   fileHeader.fileSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
        + colorTablesize + height*l_width;
    fileHeader.reserved1 = 0;
    fileHeader.reserved2 = 0;
    fileHeader.offbits=54+colorTablesize;
    fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,wf);
    infoHeader.bpp=bpp;
    infoHeader.importantColors=0;
    infoHeader.colors=0;
   
    infoHeader.biheight=height;
    infoHeader.planes=1;
    infoHeader.dwSize=40;
    infoHeader.sizeImage=l_width*height;
    infoHeader.biwidth=width;
    infoHeader.hResolution=0;
    infoHeader.vResolution=0;
    fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,wf);      
    fwrite(rgbquad,sizeof(RGBQUAD),2,wf);
    fwrite(pColorData,height*l_width,1,wf);
 
    fclose(wf);
}
 
void main()
{
     //readpath="bw2.BMP";
    readbmp();
    savebmp(pColorData1,width,height,bpp);
    free(pColorData);
    free(pColorData1);
}
2009-08-11 17:17
wenzhongyue
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-5-11
收藏
得分:0 
以上是我的代码。
2009-08-11 17:20
xufen340
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:166
专家分:1351
注 册:2009-8-7
收藏
得分:0 
看来是你以为的黑白色根本不是单色图片,32位彩色图片也可以是黑白显示,你在if (infoHeader.bpp==1) 前加一句,如:
 printf("像素数据信息:\n");  
 printf("%d\n",infoHeader.bpp) ;   
    if (infoHeader.bpp==1)  
    {   
        for(i=0;i<height;i++)  
        {  
            for(j=0;j<width;j++)  
            {  
                maxindex=*(pColorData+i*l_width+j);  
                t+=maxindex;  

假如:
1:单色;
4:16色;
8:256
16:16位
24:24位
32:32位
当然,如果等于1了,那么你就得到你要的了。
收到的鲜花
  • wenzhongyue2009-08-12 16:21 送鲜花  3朵  
2009-08-11 22:00
wenzhongyue
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-5-11
收藏
得分:0 
回复 5楼 xufen340

可是我得到的就是1啊,但是结果就是不对
2009-08-11 22:06
xufen340
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:166
专家分:1351
注 册:2009-8-7
收藏
得分:0 
一个位图是10*12,那么横向10个像素,终向12个像素,一共120个像素,如果它是一个一位图像,那么各个像素需要1位来描述像素颜色。
2009-08-11 22:47
wenzhongyue
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2007-5-11
收藏
得分:0 
回复 7楼 xufen340

这个我是知道的,我感觉我的代码是一次读了8个像素,我如何才能一次只读一个像素呢?请高手帮帮忙吧!谢谢
2009-08-12 11:09
xufen340
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:166
专家分:1351
注 册:2009-8-7
收藏
得分:0 
点一个必须知识:
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是左到右,扫描行之间是从下到上。Windows规定一个扫描行所占的字节数必须是4的倍数。
你有一句:
int l_width = WIDTHBYTES(width* infoHeader.bpp);//计算位图的实际宽度并确保它为32的倍数
再看#define   WIDTHBYTES(bits) (((bits)/8+3)/4*4) ;
根据你程序
假如:
位图第一行:32位
#define   WIDTHBYTES(bits) (((bits)/8+3)/4*4) ;
得出WIDTHBYTES(32)=7
明显错误,得出的是7。根本没有达到计算位图的实际宽度并确保它为32的倍数  

你要改成:
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)*32;
假如:
位图第一行:32位
WIDTHBYTES(32)=32,是32的倍数了。
综上所述:
#define   WIDTHBYTES(bits) (((bits)/8+3)/4*4)定义错误
如果要32的倍数,请改成:#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 32)
收到的鲜花
  • wenzhongyue2009-08-12 16:20 送鲜花  3朵  
2009-08-12 13:24
xufen340
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:166
专家分:1351
注 册:2009-8-7
收藏
得分:0 
上面#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)*32写错了,应该是#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 32),呵呵。
收到的鲜花
  • wenzhongyue2009-08-12 16:20 送鲜花  3朵  
2009-08-12 13:30
快速回复:二值图像问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025740 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved