C語言實現(xiàn)二值圖像模擬灰值圖像顯示效果
本文實例為大家分享了C語言實現(xiàn)二值圖像模擬灰值圖像顯示效果的具體代碼,供大家參考,具體內(nèi)容如下
圖案法
圖案法(patterning)是指灰度可以用一定比例的黑白點組成的區(qū)域表示,從而達(dá)到整體圖象的灰度感。黑白點的位置選擇稱為圖案化。
下面介紹的一種設(shè)計標(biāo)準(zhǔn)圖案的算法,是由Limb在1969年提出的。
先以一個2×2的矩陣開始:
通過遞歸關(guān)系有:
其中Mn和Un均為2n×2n的方陣,Un的所有元素都是1。
根據(jù)這個算法M2如下,為16級灰度的標(biāo)準(zhǔn)圖案:
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圖像文件頭,信息頭和圖像數(shù)據(jù) 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; }
代碼效果:
抖動法
假設(shè)灰度級別的范圍從b(black)到w(white),中間值t為(b+w)/2,對應(yīng)256級灰度,b=0,w=255,t=127.5。設(shè)原圖中象素的灰度為g,誤差值為e,則新圖中對應(yīng)象素的值用如下的方法得到:
if g > t then 打白點 e=g-w else 打黑點 e=g-b 3/8 × e 加到右邊的象素 3/8 × e 加到上邊的象素 1/4 × e 加到右上方的象素
實現(xiàn)代碼:
#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圖像文件頭,信息頭和圖像數(shù)據(jù) 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]; //拷貝數(shù)據(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; }
代碼效果:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++ Primer中&、*符號的多重定義與int *p和int* p的區(qū)別講解
今天小編就為大家分享一篇關(guān)于C++Primer中&、*符號的多重定義與int *p和int* p的區(qū)別講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04詳解C++編程中類的成員變量和成員函數(shù)的相關(guān)知識
這篇文章主要介紹了C++編程中類的成員變量和成員函數(shù)的相關(guān)知識,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09C++實現(xiàn)LeetCode(59.螺旋矩陣之二)
這篇文章主要介紹了C++實現(xiàn)LeetCode(59.螺旋矩陣之二),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07c++調(diào)用python實現(xiàn)圖片ocr識別
所謂c++調(diào)用python,實際上就是在c++中把整個python當(dāng)作一個第三方庫引入,然后使用特定的接口來調(diào)用python的函數(shù)或者直接執(zhí)行python腳本,本文介紹的是調(diào)用python實現(xiàn)圖片ocr識別,感興趣的可以了解下2023-09-09