欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言實(shí)現(xiàn)直方圖均衡化

 更新時(shí)間:2021年10月26日 08:28:43   作者:@leozhang  
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)直方圖均衡化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

直方圖均衡化部分是用c語(yǔ)言寫的,最后用opencv顯示原圖像,處理后圖像以及原圖和處理后圖的灰度直方圖。

雖然做出來(lái)了,均衡化效果還可以,但不知道為什么處理后圖像中有三條白線,真心搞不懂,有看出來(lái)問題的大神麻煩留言告訴我,謝謝。

(終于知道哪出問題了,原來(lái)是每行字節(jié)數(shù)求錯(cuò)了,改為L(zhǎng)ineByte=(width*8/8+3)/4*4;即可。)

下面是代碼:

#include "stdafx.h"
#include<stdio.h>
#include<windows.h>
 
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\core\core.hpp>
#include<cv.h>
  
int main(void)
{
 int width;//圖像寬度
 int height;//圖像高度
 RGBQUAD *pColorTable;
 unsigned char *pBmpBuf,*pBmpBuf1;
 BITMAPFILEHEADER bfhead;
 BITMAPINFOHEADER bihead;
 
 FILE *fp1=fopen("e:\\picture\\dog.bmp","rb");
 if(fp1==0)
  return 0;
 fread(&bfhead,14,1,fp1);
 fread(&bihead,40,1,fp1);
 width=bihead.biWidth;
 height=bihead.biHeight;
 
 pColorTable=new RGBQUAD[256];
 fread(pColorTable,4,256,fp1);
 int LineByte=0;
 LineByte=(width*1/4+1)*4;
<span style="white-space:pre"> </span>//LineByte=(width*8/8+3)/4*4;
 pBmpBuf = new unsigned char[LineByte*height];
 
 fread(pBmpBuf,LineByte*height,1,fp1);
 fclose(fp1);
 
 pBmpBuf1=new unsigned char[LineByte*height]; //用于存儲(chǔ)均值化后的圖像數(shù)據(jù)
 //統(tǒng)計(jì)每個(gè)灰度級(jí)像素點(diǎn)的個(gè)數(shù)
 int N[256]={0};
 for(int i=0;i<height;i++)
  for(int j=0;j<width;j++)
  {
   unsigned char *pb1,*pb2;
   pb1=pBmpBuf+i*LineByte+j;
   N[*pb1]++;
   pb2=pBmpBuf1+i*LineByte+j;
   *pb2=*pb1; 
  }
 /*for(int i=0;i<256;i++ )
  printf("%d  ",N[i]);*/
 
 
  //統(tǒng)計(jì)最小與最大灰度值
  int minGrayValue=255;    
  int maxGrayValue=0;
 for(int i=0;i<height;i++)
  for(int j=0;j<width;j++)
  {
   unsigned char *pb;
   pb=pBmpBuf+i*LineByte+j;
   if(*pb>maxGrayValue)
    maxGrayValue=*pb;
   else if(*pb<minGrayValue)
    minGrayValue=*pb;
  }
  printf("%d ,%d\n",minGrayValue,maxGrayValue);//輸出最大與最小灰度值
 
  int x=maxGrayValue-minGrayValue+1;
  float *p;
  p=new float[x];
  
  for(int i=0;i<x;i++)
  {
   *(p+i)=(float)N[i]/(float)(width*height);   //*(p+i)中存放的是灰度級(jí)為i的像素在整幅圖像中出現(xiàn)
                                                  //的概率(即*(p+i)i=0,1,2,3...中存放的就是這幅圖像歸一化后的直方圖) 
  }
  
  
  float *c;
  c=new float[x];      //定義c,用來(lái)存放累積的歸一化直方圖
  for(int i=0;i<x;i++)  //對(duì)c進(jìn)行初始化
  {
   *(c+i)=0;
 
  }
 
  for(int i=0;i<x;i++)
  {
   for(int j=0;j<=i;j++)
   {
    *(c+i)+=*(p+j);
   }
  }




  for(int i=0;i<height;i++)
   for(int j=0;j<width;j++)
   {
    unsigned char *pb;
    pb=pBmpBuf1+i*LineByte+j;
    *pb=*(c+*pb)*(maxGrayValue-minGrayValue)+minGrayValue;
   }
 
  FILE *fp2=fopen("junhenghua.bmp","wb");
  fwrite(&bfhead,14,1,fp2);
  fwrite(&bihead,40,1,fp2);
  fwrite(pColorTable,4,256,fp2);
  fwrite(pBmpBuf1,LineByte*height,1,fp2);
  fclose(fp2);
  
  
//顯示原圖與處理后的圖像
  IplImage *src1=cvLoadImage("e:\\picture\\dog.bmp");
  IplImage *src2=cvLoadImage("junhenghua.bmp");
 
  cvNamedWindow("原圖");
  cvNamedWindow("處理后圖");
 
  cvShowImage("原圖",src1);
  cvShowImage("處理后圖",src2);
 
//顯示原圖像與處理后圖像的灰度直方圖
 int size=256;
 float range[]={0,255};
 float *ranges[]={range};
 CvHistogram *hist1=cvCreateHist(1,&size, CV_HIST_ARRAY,ranges,1);//創(chuàng)建一維直方圖,
 CvHistogram *hist2=cvCreateHist(1,&size, CV_HIST_ARRAY,ranges,1);
 IplImage* gray1=cvCreateImage(cvGetSize(src1),8,1);
 IplImage* gray2=cvCreateImage(cvGetSize(src2),8,1);
 cvCvtColor(src1,gray1,CV_BGR2GRAY); 
 cvCvtColor(src2,gray2,CV_BGR2GRAY);
 //vCvtColor(...),是Opencv里的顏色空間轉(zhuǎn)換函數(shù),可以實(shí)現(xiàn)RGB顏色向HSV,HSI等顏色空間的轉(zhuǎn)換,也可以轉(zhuǎn)換為灰度圖像。
 //參數(shù)CV_RGB2GRAY是RGB到gray,
    //參數(shù)CV_GRAY2RGB是gray到RGB
 
 cvCalcHist(&gray1,hist1,0,0);//統(tǒng)計(jì)圖像在[0 255]像素的均勻分布,將統(tǒng)計(jì)結(jié)果存在結(jié)構(gòu)體中
 cvCalcHist(&gray2,hist2,0,0);
 
 //draw histogram-----
 
 //統(tǒng)計(jì)直方圖中的最大直方塊
 float histMax1=0,histMax2=0;
 cvGetMinMaxHistValue(hist1,0,&histMax1,0);     
 cvGetMinMaxHistValue(hist2,0,&histMax2,0);
 //創(chuàng)建一張一維直方圖的“圖”,橫坐標(biāo)為灰度級(jí),縱坐標(biāo)為像素個(gè)數(shù)  
 IplImage *grayHist1=cvCreateImage(cvSize(256*2,64*2),8,1);
 IplImage *grayHist2=cvCreateImage(cvSize(256*2,64*2),8,1);
 cvZero(grayHist1);
 cvZero(grayHist2);
 
 //分別將每個(gè)直方塊的值繪制到圖中  
 for(int i=0;i<255;i++)
 {
  float histValue=cvQueryHistValue_1D(hist1,i);
  float nextValue=cvQueryHistValue_1D(hist1,i+1);
 
  //計(jì)算直方塊4個(gè)點(diǎn)的值
  CvPoint pt1=cvPoint(i*2,64*2);
  CvPoint pt2=cvPoint((i+1)*2,64*2);
  CvPoint pt3=cvPoint((i+1)*2,(64-(nextValue/histMax1)*64)*2);
  //nextValue/histMax是將i級(jí)像素點(diǎn)個(gè)數(shù)歸一到0~1,在*64是使其高對(duì)在0~64之間
  //由于opencv圖像是以左上角為坐標(biāo)原點(diǎn),向右為x軸,向下時(shí)y軸,而顯示的直方圖是向上增長(zhǎng)的,所以用64減,將其倒過(guò)來(lái)顯示
  CvPoint pt4=cvPoint(i*2,   (64-(histValue/histMax1)*64)*2);
 
  int ptNum=5;
  CvPoint pt[5];
  pt[0]=pt1;
  pt[1]=pt2;
  pt[2]=pt3;
  pt[3]=pt4;
  pt[4]=pt1;
 
        cvFillConvexPoly(grayHist1,pt,ptNum,cvScalar(255)); //填充直方塊
     
 
 }
 
 for(int i=0;i<255;i++)
 {
  float histValue=cvQueryHistValue_1D(hist2,i);
  float nextValue=cvQueryHistValue_1D(hist2,i+1);
 
  //計(jì)算直方塊4個(gè)點(diǎn)的值
  CvPoint pt1=cvPoint(i*2,64*2);
  CvPoint pt2=cvPoint((i+1)*2,64*2);
  CvPoint pt3=cvPoint((i+1)*2,(64-(nextValue/histMax2)*64)*2);
  //nextValue/histMax是將i級(jí)像素點(diǎn)個(gè)數(shù)歸一到0~1,在*64是使其高對(duì)在0~64之間
  //由于opencv圖像是以左上角為坐標(biāo)原點(diǎn),向右為x軸,向下時(shí)y軸,而顯示的直方圖是向上增長(zhǎng)的,所以用64減,將其倒過(guò)來(lái)顯示
  CvPoint pt4=cvPoint(i*2,   (64-(histValue/histMax2)*64)*2);
 
  int ptNum=5;
  CvPoint pt[5];
  pt[0]=pt1;
  pt[1]=pt2;
  pt[2]=pt3;
  pt[3]=pt4;
  pt[4]=pt1;
 
        cvFillConvexPoly(grayHist2,pt,ptNum,cvScalar(255)); //填充直方塊
     
 
 }
 
 cvNamedWindow("grayHistogram1");
 cvNamedWindow("grayHistogram2");
 cvShowImage("grayHistogram1",grayHist1);
 cvShowImage("grayHistogram2",grayHist2);
 
 
  cvWaitKey(0);
 
 system("pause");
 
return 0;  
}

原圖:

處理后圖:

原圖直方圖:

均衡化后直方圖:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解VSCode下C++環(huán)境配置過(guò)程

    詳解VSCode下C++環(huán)境配置過(guò)程

    這篇文章主要介紹了VSCode C++環(huán)境配置過(guò)程,在這大家需要在代碼的目錄下的.vscode文件夾下創(chuàng)建launch.json、tasks.json,具體實(shí)現(xiàn)過(guò)程跟隨小編一起看看吧
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)學(xué)生籍貫信息記錄簿

    C語(yǔ)言實(shí)現(xiàn)學(xué)生籍貫信息記錄簿

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生籍貫信息記錄簿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 一起來(lái)練習(xí)C++的指針

    一起來(lái)練習(xí)C++的指針

    這篇文章主要為大家詳細(xì)介紹了C++的指針,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • VS及Unity安裝和使用Nuget包

    VS及Unity安裝和使用Nuget包

    本文主要介紹了VS及Unity安裝和使用Nuget包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • c++中引用作為形參的使用方法以及作用

    c++中引用作為形參的使用方法以及作用

    這篇文章主要給大家介紹了關(guān)于c++中引用作為形參的使用方法以及作用的相關(guān)資料,引用是地址傳值,作為引用的形參數(shù)值被修改的同時(shí),也修改了對(duì)應(yīng)實(shí)參的值,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • OpenCV+Qt實(shí)現(xiàn)圖像處理操作

    OpenCV+Qt實(shí)現(xiàn)圖像處理操作

    這篇文章主要為大家詳細(xì)介紹了OpenCV+Qt實(shí)現(xiàn)圖像處理操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++ 設(shè)置控制臺(tái)(命令行)窗口 光標(biāo)位置,及前背景顏色

    C++ 設(shè)置控制臺(tái)(命令行)窗口 光標(biāo)位置,及前背景顏色

    這篇文章主要介紹了C++ 設(shè)置控制臺(tái)(命令行)窗口 光標(biāo)位置,及前背景顏色,需要的朋友可以參考下
    2019-04-04
  • C語(yǔ)言+win32api寫窗體應(yīng)用程序

    C語(yǔ)言+win32api寫窗體應(yīng)用程序

    本文給大家分享的是個(gè)人使用純C語(yǔ)言結(jié)合win32api制作窗體應(yīng)用程序的代碼,非常的簡(jiǎn)單,給需要的小伙伴參考下。
    2016-02-02
  • C++實(shí)現(xiàn)將輸入復(fù)制到輸出的方法

    C++實(shí)現(xiàn)將輸入復(fù)制到輸出的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)將輸入復(fù)制到輸出的方法,實(shí)例分析了C++字符串轉(zhuǎn)換及輸入輸出操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程

    C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程

    這篇文章主要介紹了C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程,了解內(nèi)部原理是為了幫助我們做擴(kuò)展,同時(shí)也是驗(yàn)證了一個(gè)人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會(huì)的,跟隨下文來(lái)具體了解吧
    2023-02-02

最新評(píng)論