欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C语言实现二值图像模拟灰值图像显示效果

程序员文章站 2022-06-24 10:21:18
本文实例为大家分享了c语言实现二值图像模拟灰值图像显示效果的具体代码,供大家参考,具体内容如下图案法图案法(patterning)是指灰度可以用一定比例的黑白点组成的区域表示,从而达到整体图象的灰度感...

本文实例为大家分享了c语言实现二值图像模拟灰值图像显示效果的具体代码,供大家参考,具体内容如下

图案法

图案法(patterning)是指灰度可以用一定比例的黑白点组成的区域表示,从而达到整体图象的灰度感。黑白点的位置选择称为图案化。

下面介绍的一种设计标准图案的算法,是由limb在1969年提出的。

先以一个2×2的矩阵开始:

C语言实现二值图像模拟灰值图像显示效果

通过递归关系有:

C语言实现二值图像模拟灰值图像显示效果

其中mn和un均为2n×2n的方阵,un的所有元素都是1。
根据这个算法m2如下,为16级灰度的标准图案:

C语言实现二值图像模拟灰值图像显示效果

m3(8×8阵)比较特殊,称为bayer抖动表。m4是一个16×16的矩阵。

m3 表模拟灰值图像显示效果:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma pack(1)   //全紧凑模式

typedef struct {
 unsigned char bftype[2];
 unsigned long bfsize;
 unsigned short bfreserved1;
 unsigned short bfreserved2;
 unsigned long bfoffbits;
}bitmapfileheader;

typedef struct {
 unsigned long bisize;
 unsigned long biwidth;
 unsigned long biheight;
 unsigned short biplanes;
 unsigned short bibitcount;
 unsigned long bicompression;
 unsigned long bisizeimage;
 long bixpixpermeter;
 long biypixpermeter;
 unsigned long biclrused;
 unsigned long biclrimportant;
}bitmapinfoheader;


typedef struct{
 unsigned char rgbblue;
 unsigned char rgbgreen;
 unsigned char rgbred;
 unsigned char rgbreserved;

}rgbquad;

typedef struct{
 bitmapfileheader bfheader;
 bitmapinfoheader biheader;
 rgbquad palette[256];
 unsigned char *imgdata;
}bmp;

int main(){
 file *fp;
 if((fp=fopen("d:\temp\\test_gray.bmp","rb"))==null){
  perror("can not open file!");
  return -1;
 }
 //读入彩色bmp图像文件头,信息头和图像数据
 bitmapfileheader bfheader;
 fread(&bfheader,14,1,fp);
 bitmapinfoheader biheader;
 fread(&biheader,40,1,fp);
 int imsize=biheader.bisizeimage;
 int width=biheader.biwidth;
 int height=biheader.biheight;
 int bitcount=biheader.bibitcount;
 int linebytes=(width*bitcount+31)/32*4;
 
 fseek(fp,bfheader.bfoffbits,seek_set);
 unsigned char*imagedata=(unsigned char*)malloc(imsize*sizeof(unsigned char));
 fread(imagedata,imsize*sizeof(unsigned char),1,fp); 
 fclose(fp);

 bmp b;
 memcpy(&(b.bfheader),&bfheader,sizeof(bfheader));
 memcpy(&(b.biheader),&biheader,sizeof(biheader));
 b.imgdata=(unsigned char*)malloc(sizeof(unsigned char)*imsize);
 memset(b.imgdata,0,sizeof(unsigned char)*imsize);
 for(int i=0;i<256;i++){
  b.palette[i].rgbblue=i;
  b.palette[i].rgbgreen=i;
  b.palette[i].rgbred=i;
 }
 
 int i,j,temp;
 unsigned char bayer[8][8]={  
  0,32,8,40,2,34,10,42,
  48,16,56,24,50,18,58,26,
  12,44,4,36,14,46,6,38,
  60,28,52,20,62,30,54,22,
  3,35,11,43,1,33,9,41,
        51,19,59,27,49,17,57,25,
  15,47,7,39,13,45,5,37,
        63,31,55,23,61,29,53,21
 };
 for(i=0;i<height;i++){ 
  for(j=0;j<width;j++){ 
   temp=imagedata[linebytes*i+j];
   if((temp>>2)>bayer[i&7][j&7])
    b.imgdata[linebytes*i+j]=255;
   else
    b.imgdata[linebytes*i+j]=0;
  }
 }
 
 char savepath[]="d:\temp\\save_test.bmp";
 file *f_save=fopen(savepath,"wb");
 if(f_save==null){
  perror("can not open file!");
  return -2;
 }

 fwrite(&b.bfheader,sizeof(bitmapfileheader),1,f_save);
 fwrite(&b.biheader,sizeof(bitmapinfoheader),1,f_save);
 fwrite(&b.palette,1024,1,f_save);
 fwrite(b.imgdata,sizeof(unsigned char)*b.biheader.bisizeimage,1,f_save);
 fclose(f_save);
 
 free(imagedata);
 free(b.imgdata);
 getchar();
 return 0;
}

代码效果:

C语言实现二值图像模拟灰值图像显示效果

抖动法

假设灰度级别的范围从b(black)到w(white),中间值t为(b+w)/2,对应256级灰度,b=0,w=255,t=127.5。设原图中象素的灰度为g,误差值为e,则新图中对应象素的值用如下的方法得到:

if g > t then
  打白点
  e=g-w
else 
  打黑点
  e=g-b
 3/8 × e 加到右边的象素
 3/8 × e 加到上边的象素
 1/4 × e 加到右上方的象素

实现代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma pack(1)   //全紧凑模式

typedef struct {
 unsigned char bftype[2];
 unsigned long bfsize;
 unsigned short bfreserved1;
 unsigned short bfreserved2;
 unsigned long bfoffbits;
}bitmapfileheader;

typedef struct {
 unsigned long bisize;
 unsigned long biwidth;
 unsigned long biheight;
 unsigned short biplanes;
 unsigned short bibitcount;
 unsigned long bicompression;
 unsigned long bisizeimage;
 long bixpixpermeter;
 long biypixpermeter;
 unsigned long biclrused;
 unsigned long biclrimportant;
}bitmapinfoheader;


typedef struct{
 unsigned char rgbblue;
 unsigned char rgbgreen;
 unsigned char rgbred;
 unsigned char rgbreserved;

}rgbquad;

typedef struct{
 bitmapfileheader bfheader;
 bitmapinfoheader biheader;
 rgbquad palette[256];
 unsigned char *imgdata;
}bmp;

int main(){
 file *fp;
 if((fp=fopen("d:\temp\\test_gray.bmp","rb"))==null){
  perror("can not open file!");
  return -1;
 }
 //读入彩色bmp图像文件头,信息头和图像数据
 bitmapfileheader bfheader;
 fread(&bfheader,14,1,fp);
 bitmapinfoheader biheader;
 fread(&biheader,40,1,fp);
 int imsize=biheader.bisizeimage;
 int width=biheader.biwidth;
 int height=biheader.biheight;
 int bitcount=biheader.bibitcount;
 int linebytes=(width*bitcount+31)/32*4;
 
 fseek(fp,bfheader.bfoffbits,seek_set);
 unsigned char*imagedata=(unsigned char*)malloc(imsize*sizeof(unsigned char));
 fread(imagedata,imsize*sizeof(unsigned char),1,fp); 
 fclose(fp);

 bmp b;
 memcpy(&(b.bfheader),&bfheader,sizeof(bfheader));
 memcpy(&(b.biheader),&biheader,sizeof(biheader));
 b.imgdata=(unsigned char*)malloc(sizeof(unsigned char)*imsize);
 memset(b.imgdata,0,sizeof(unsigned char)*imsize);
 for(int i=0;i<256;i++){
  b.palette[i].rgbblue=i;
  b.palette[i].rgbgreen=i;
  b.palette[i].rgbred=i;
 }
 
 int i,j,temp;
 double e,f;
 for(i=0;i<height;i++){
  for(j=0;j<width;j++){
   b.imgdata[linebytes*i+j]=imagedata[linebytes*i+j]; //拷贝数据
  }
 }
 
 for(i=0;i<height;i++){ 
  for(j=0;j<width;j++){ 
   temp=b.imgdata[linebytes*i+j];
   if(temp>128){
    b.imgdata[linebytes*i+j]=255;
    e=(float)(temp-255);
   }
   else{
    b.imgdata[linebytes*i+j]=0;
    e=(float)temp;
   }
   if(j<width-1){
    f=b.imgdata[linebytes*i+j+1];
    f+=3.0/8.0*e;
    b.imgdata[linebytes*i+j+1]=(unsigned char)f; //向右传播
   }
   if(i<height-1){
    f=b.imgdata[linebytes*(i+1)+j];
    f+=3.0/8.0*e;
    b.imgdata[linebytes*(i+1)+j]=(unsigned char)f; //向上传播
    f=b.imgdata[linebytes*(i+1)+j+1];
    f+=1.0/4.0*e;
    b.imgdata[linebytes*(i+1)+j+1]=(unsigned char)f; //向右上传播
   }
  }
 }
 
 
 char savepath[]="d:\temp\\save_test.bmp";
 file *f_save=fopen(savepath,"wb");
 if(f_save==null){
  perror("can not open file!");
  return -2;
 }

 fwrite(&b.bfheader,sizeof(bitmapfileheader),1,f_save);
 fwrite(&b.biheader,sizeof(bitmapinfoheader),1,f_save);
 fwrite(&b.palette,1024,1,f_save);
 fwrite(b.imgdata,sizeof(unsigned char)*b.biheader.bisizeimage,1,f_save);
 fclose(f_save);
 
 free(imagedata);
 free(b.imgdata);
 getchar();
 return 0;
}

代码效果:

C语言实现二值图像模拟灰值图像显示效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。