2#include3#include4#include5#include6#include7#include89/*灰度級結(jié)點(diǎn)*/10typedefstruct{11intpixels;//灰度級對應(yīng)像素個數(shù)12flo" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

直方圖均衡化的 C++ 實(shí)現(xiàn)(基于 openCV)

系統(tǒng) 4909 0

這是數(shù)字圖像處理課的大作業(yè),完成于 2013/06/17,需要調(diào)用 openCV 庫,完整源碼和報(bào)告如下:

?

        
            1
        
         #include <cv.h>


        
            2
        
         #include <highgui.h>


        
            3
        
         #include <stdio.h>


        
            4
        
         #include <stdlib.h>


        
            5
        
         #include <math.h>


        
            6
        
         #include <assert.h>


        
            7
        
         #include <
        
          string
        
        >


        
            8
        
        
            9
        
        
          /*
        
        
           灰度級結(jié)點(diǎn) 
        
        
          */
        
        
           10
        
         typedef 
        
          struct
        
        
           {


        
        
           11
        
        
          int
        
         pixels;        
        
          //
        
        
           灰度級對應(yīng)像素個數(shù)
        
        
           12
        
        
          float
        
         rate;        
        
          //
        
        
           像素比例
        
        
           13
        
        
          float
        
         accuRate;    
        
          //
        
        
           累計(jì)像素比例
        
        
           14
        
        
          int
        
         map;        
        
          //
        
        
           到均衡化后的灰度級的映射
        
        
           15
        
        
          } levNode;


        
        
           16
        
        
           17
        
        
          void
        
         histeqGray(IplImage* pGray, 
        
          int
        
         levels, 
        
          int
        
        
           argc);


        
        
           18
        
         IplImage* histImage(IplImage* pSrc, 
        
          int
        
         histWidth, 
        
          int
        
         histHeight, 
        
          int
        
        
           nScale);


        
        
           19
        
        
           20
        
        
          int
        
         main(
        
          int
        
         argc, 
        
          char
        
        *
        
           argv[])


        
        
           21
        
        
          {


        
        
           22
        
        
          int
        
        
           levels;


        
        
           23
        
             std::
        
          string
        
        
           imgName, inTmp;


        
        
           24
        
        
          if
        
         (argc == 
        
          3
        
        
          ) {


        
        
           25
        
                 levels = atoi(argv[
        
          1
        
        
          ]);


        
        
           26
        
                 imgName = argv[
        
          2
        
        
          ];


        
        
           27
        
        
              } 


        
        
           28
        
        
          else
        
        
          if
        
         (argc == 
        
          2
        
        
          )


        
        
           29
        
                 imgName = argv[
        
          1
        
        
          ];


        
        
           30
        
        
          else
        
        
           {


        
        
           31
        
                 printf(
        
          "
        
        
          usage: histeq [levels] image_name \n
        
        
          "
        
        
          );


        
        
           32
        
        
          return
        
         -
        
          1
        
        
          ;


        
        
           33
        
        
              }


        
        
           34
        
        
           35
        
             IplImage* pSrc =
        
           cvLoadImage(imgName.c_str(), CV_LOAD_IMAGE_UNCHANGED);


        
        
           36
        
        
          int
        
         channel = pSrc->
        
          nChannels;


        
        
           37
        
        
           38
        
             IplImage* pChnl[
        
          4
        
        ] =
        
           { NULL };


        
        
           39
        
        
           40
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < channel; ++
        
          i)


        
        
           41
        
                 pChnl[i] = cvCreateImage(cvGetSize(pSrc), pSrc->depth, 
        
          1
        
        
          );


        
        
           42
        
        
           43
        
             cvSplit(pSrc, pChnl[
        
          0
        
        ], pChnl[
        
          1
        
        ], pChnl[
        
          2
        
        ], pChnl[
        
          3
        
        
          ]);


        
        
           44
        
        
           45
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < channel; ++
        
          i)


        
        
           46
        
        
                  histeqGray(pChnl[i], levels, argc);


        
        
           47
        
        
           48
        
             IplImage* pEql = cvCreateImage(cvGetSize(pSrc), pChnl[
        
          0
        
        ]->depth, pSrc->
        
          nChannels);


        
        
           49
        
        
           50
        
             cvMerge(pChnl[
        
          0
        
        ], pChnl[
        
          1
        
        ], pChnl[
        
          2
        
        ], pChnl[
        
          3
        
        
          ], pEql);


        
        
           51
        
        
           52
        
             inTmp = imgName + 
        
          "
        
        
          _Eql.jpg
        
        
          "
        
        
          ;


        
        
           53
        
        
              cvSaveImage(inTmp.c_str(), pEql);


        
        
           54
        
        
           55
        
        
          //
        
        
          cvNamedWindow(imgName.c_str(), CV_WINDOW_AUTOSIZE);
        
        
           56
        
        
              cvShowImage(imgName.c_str(), pSrc);


        
        
           57
        
        
          //
        
        
          cvNamedWindow(inTmp.c_str(), CV_WINDOW_AUTOSIZE);
        
        
           58
        
        
              cvShowImage(inTmp.c_str(), pEql);


        
        
           59
        
        
           60
        
             IplImage* pSrcGray = cvCreateImage(cvGetSize(pSrc), IPL_DEPTH_8U, 
        
          1
        
        
          );


        
        
           61
        
        
          if
        
         (pSrc->nChannels == 
        
          3
        
        
          )


        
        
           62
        
        
                  cvCvtColor(pSrc, pSrcGray, CV_BGR2GRAY);


        
        
           63
        
        
          else
        
        
           64
        
        
                  cvCopyImage(pSrc, pSrcGray);


        
        
           65
        
             IplImage* pEqlGray = cvCreateImage(cvGetSize(pEql), IPL_DEPTH_8U, 
        
          1
        
        
          );


        
        
           66
        
        
          if
        
         (pSrc->nChannels == 
        
          3
        
        
          )


        
        
           67
        
        
                  cvCvtColor(pEql, pEqlGray, CV_BGR2GRAY);


        
        
           68
        
        
          else
        
        
           69
        
        
                  cvCopyImage(pEql, pEqlGray);


        
        
           70
        
             imgName += 
        
          "
        
        
          _Hist.jpg
        
        
          "
        
        
          ;


        
        
           71
        
             inTmp += 
        
          "
        
        
          _Hist.jpg
        
        
          "
        
        
          ;


        
        
           72
        
        
          int
        
         nScale = 
        
          2
        
        
          ;


        
        
           73
        
        
          int
        
         histWidth = 
        
          /*
        
        
          pSrc->width * nScale
        
        
          */
        
        
          256
        
         *
        
           nScale;


        
        
           74
        
        
          int
        
         histHeight = 
        
          /*
        
        
          pSrc->height
        
        
          */
        
        
          128
        
        
          ;


        
        
           75
        
             IplImage* pSrcGrayHist =
        
           histImage(pSrcGray, histWidth, histHeight, nScale);


        
        
           76
        
             IplImage* pEqlGrayHist =
        
           histImage(pEqlGray, histWidth, histHeight, nScale);


        
        
           77
        
        
              cvSaveImage(imgName.c_str(), pSrcGrayHist);


        
        
           78
        
        
              cvSaveImage(inTmp.c_str(), pEqlGrayHist);


        
        
           79
        
        
              cvShowImage(imgName.c_str(), pSrcGrayHist);


        
        
           80
        
        
              cvShowImage(inTmp.c_str(), pEqlGrayHist);


        
        
           81
        
        
           82
        
        
              cvWaitKey();


        
        
           83
        
        
           84
        
             cvReleaseImage(&
        
          pEql);


        
        
           85
        
             cvReleaseImage(&
        
          pEqlGray);


        
        
           86
        
        
          for
        
         (
        
          int
        
         i = 
        
          0
        
        ; i < channel; ++
        
          i)


        
        
           87
        
                 cvReleaseImage(&
        
          pChnl[i]);


        
        
           88
        
             cvReleaseImage(&
        
          pSrc);


        
        
           89
        
             cvReleaseImage(&
        
          pSrcGray);


        
        
           90
        
        
           91
        
        
          return
        
        
          0
        
        
          ;


        
        
           92
        
        
          }


        
        
           93
        
        
           94
        
        
          /*
        
        
           95
        
        
          * 直方圖均衡化函數(shù) 


        
        
           96
        
        
          * pGray為輸入的灰度圖


        
        
           97
        
        
          * levels為均衡化的灰度級


        
        
           98
        
        
          */
        
        
           99
        
        
          void
        
         histeqGray(IplImage* pGray, 
        
          int
        
         levels, 
        
          int
        
        
           argc)


        
        
          100
        
        
          {


        
        
          101
        
        
          int
        
         depth = pGray->
        
          depth;


        
        
          102
        
             printf(
        
          "
        
        
          %d \n
        
        
          "
        
        
          , depth);


        
        
          103
        
        
          int
        
         width = pGray->
        
          width;


        
        
          104
        
        
          int
        
         height = pGray->
        
          height;


        
        
          105
        
        
          int
        
         sumPixels = width * height;        
        
          //
        
        
           總像素?cái)?shù)
        
        
          106
        
             printf(
        
          "
        
        
          %d \n
        
        
          "
        
        
          , sumPixels);


        
        
          107
        
        
          int
        
         values = static_cast<
        
          int
        
        >(pow((
        
          float
        
        )
        
          2
        
        , depth)); 
        
          //
        
        
           根據(jù)圖像深度計(jì)算像素取值范圍
        
        
          108
        
        
          if
        
         (argc == 
        
          2
        
        ) levels =
        
           values;


        
        
          109
        
             printf(
        
          "
        
        
          %d \n
        
        
          "
        
        
          , levels);


        
        
          110
        
        
          111
        
        
          int
        
        
           outDepth;


        
        
          112
        
        
          /*
        
        
          if (levels <= 2)


        
        
          113
        
        
                  outDepth = 1;


        
        
          114
        
        
              else
        
        
          */
        
        
          if
        
         (levels <= 
        
          256
        
        
          )


        
        
          115
        
                 outDepth = 
        
          8
        
        
          ;


        
        
          116
        
        
          else
        
        
          if
        
         (levels <= 
        
          65536
        
        
          )


        
        
          117
        
                 outDepth = 
        
          16
        
        
          ;


        
        
          118
        
        
          119
        
             assert(levels <=
        
           values);


        
        
          120
        
        
          int
        
         intervals = values / levels; 
        
          //
        
        
           根據(jù)像素取值范圍和灰度級求每個灰度級的像素間隔
        
        
          121
        
             levNode* levNodes = (levNode*)calloc(levels, 
        
          sizeof
        
        (levNode)); 
        
          //
        
        
           生成灰度結(jié)點(diǎn)


        
        
          122
        
        
          //
        
        
          for (int lev = 0; lev < levels; ++lev) printf("%d \n", levNodes[lev].pixels);


        
        
          123
        
        
          //
        
        
          char* pValues = pGray->imageData;
        
        
          124
        
        
          125
        
        
          /*
        
        
           統(tǒng)計(jì)每個灰度級的像素個數(shù) 
        
        
          */
        
        
          126
        
        
          for
        
         (
        
          int
        
         y = 
        
          0
        
        ; y < height; ++
        
          y)


        
        
          127
        
        
          for
        
         (
        
          int
        
         x = 
        
          0
        
        ; x < width; ++
        
          x) {


        
        
          128
        
                     CvScalar scal =
        
           cvGet2D(pGray, y, x);


        
        
          129
        
        
          int
        
         val = (
        
          int
        
        )scal.val[
        
          0
        
        
          ];


        
        
          130
        
        
          //
        
        
          printf("%d \n", val);
        
        
          131
        
        
          for
        
         (
        
          int
        
         lev = 
        
          0
        
        ; lev < levels; ++
        
          lev) {


        
        
          132
        
        
          if
        
         ( val >= intervals*lev && val < intervals*(lev+
        
          1
        
        
          )) {


        
        
          133
        
                             ++levNodes[lev].pixels; 
        
          break
        
        
          ;


        
        
          134
        
        
                          }


        
        
          135
        
        
                      }


        
        
          136
        
        
                  }


        
        
          137
        
        
          138
        
        
          int
        
         sum = 
        
          0
        
        
          ;


        
        
          139
        
        
          for
        
         (
        
          int
        
         lev = 
        
          0
        
        ; lev < levels; ++
        
          lev)


        
        
          140
        
                 sum +=
        
           levNodes[lev].pixels;


        
        
          141
        
             printf(
        
          "
        
        
          %d \n
        
        
          "
        
        
          , sum);


        
        
          142
        
        
          143
        
        
          /*
        
        
           計(jì)算每個灰度級像素比例和累計(jì)比例 
        
        
          */
        
        
          144
        
             levNodes[
        
          0
        
        ].accuRate = levNodes[
        
          0
        
        ].rate = levNodes[
        
          0
        
        ].pixels / (
        
          float
        
        
          )sumPixels;


        
        
          145
        
             levNodes[
        
          0
        
        ].map = (
        
          int
        
        )(levNodes[
        
          0
        
        ].accuRate * (levels - 
        
          1
        
        ) + 
        
          0.5
        
        
          );


        
        
          146
        
             printf(
        
          "
        
        
          %d \n
        
        
          "
        
        , levNodes[
        
          0
        
        
          ].pixels);


        
        
          147
        
        
          for
        
         (
        
          int
        
         lev = 
        
          1
        
        ; lev < levels; ++
        
          lev) {


        
        
          148
        
                 levNodes[lev].rate = levNodes[lev].pixels / (
        
          float
        
        
          )sumPixels;


        
        
          149
        
                 levNodes[lev].accuRate = levNodes[lev-
        
          1
        
        ].accuRate +
        
           levNodes[lev].rate;


        
        
          150
        
                 levNodes[lev].map = (
        
          int
        
        )(levNodes[lev].accuRate * (levels - 
        
          1
        
        ) + 
        
          0.5
        
        
          );


        
        
          151
        
        
              }


        
        
          152
        
             printf(
        
          "
        
        
          %f \n
        
        
          "
        
        , levNodes[levels-
        
          1
        
        
          ].accuRate);


        
        
          153
        
        
          154
        
        
          /*
        
        
           生成均衡化后的圖像 
        
        
          */
        
        
          155
        
        
          for
        
         (
        
          int
        
         y = 
        
          0
        
        ; y < height; ++
        
          y)


        
        
          156
        
        
          for
        
         (
        
          int
        
         x = 
        
          0
        
        ; x < width; ++
        
          x) {


        
        
          157
        
                     CvScalar scal =
        
           cvGet2D(pGray, y, x);


        
        
          158
        
        
          int
        
         val = (
        
          int
        
        )scal.val[
        
          0
        
        
          ];


        
        
          159
        
        
          //
        
        
          printf("%d \n", val);
        
        
          160
        
        
          for
        
         (
        
          int
        
         lev = 
        
          0
        
        ; lev < levels; ++
        
          lev) {


        
        
          161
        
        
          if
        
         (val >= intervals*lev && val < intervals*(lev+
        
          1
        
        
          )) {                    


        
        
          162
        
                                 scal.val[
        
          0
        
        ] =
        
           levNodes[lev].map;


        
        
          163
        
        
          //
        
        
          printf("%f \n", scal.val[0]);
        
        
          164
        
        
                                  cvSet2D(pGray, y, x, scal);


        
        
          165
        
        
          break
        
        
          ;


        
        
          166
        
        
                          }


        
        
          167
        
        
                      }


        
        
          168
        
        
                  }


        
        
          169
        
             pGray->depth =
        
           outDepth;


        
        
          170
        
        
          171
        
        
              free(levNodes);


        
        
          172
        
        
          }


        
        
          173
        
        
          174
        
        
          /*
        
        
          175
        
        
          * 繪制直方圖函數(shù)


        
        
          176
        
        
          */
        
        
          177
        
         IplImage* histImage(IplImage* pSrc, 
        
          int
        
         histWidth, 
        
          int
        
         histHeight, 
        
          int
        
        
           nScale)


        
        
          178
        
        
          {


        
        
          179
        
        
          int
        
         histSize = static_cast<
        
          int
        
        >(pow((
        
          float
        
        )
        
          2
        
        , pSrc->
        
          depth));


        
        
          180
        
             CvHistogram* pHist = cvCreateHist(
        
          /*
        
        
          pSrc->nChannels
        
        
          */
        
        
          1
        
        , &
        
          histSize, CV_HIST_ARRAY);


        
        
          181
        
             cvCalcHist(&
        
          pSrc, pHist);


        
        
          182
        
        
          183
        
             IplImage* pHistImg = cvCreateImage(cvSize(histWidth, histHeight), IPL_DEPTH_8U, 
        
          1
        
        
          );


        
        
          184
        
             cvRectangle(pHistImg, cvPoint(
        
          0
        
        ,
        
          0
        
        ), cvPoint(pHistImg->width,pHistImg->height), CV_RGB(
        
          255
        
        ,
        
          255
        
        ,
        
          255
        
        
          ), CV_FILLED);


        
        
          185
        
        
          186
        
        
          float
        
         histMaxVal = 
        
          0
        
        
          ;


        
        
          187
        
             cvGetMinMaxHistValue(pHist, 
        
          0
        
        , &
        
          histMaxVal);


        
        
          188
        
        
          189
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < histSize; i++
        
          )


        
        
          190
        
        
              {


        
        
          191
        
        
          float
        
         histValue= cvQueryHistValue_1D(pHist, i); 
        
          //
        
        
           像素為i的直方塊大小
        
        
          192
        
        
          int
        
         nRealHeight = cvRound((histValue / histMaxVal) * histHeight);  
        
          //
        
        
           要繪制的高度
        
        
          193
        
        
                  cvRectangle(pHistImg,  


        
        
          194
        
                     cvPoint(i*nScale, histHeight - 
        
          1
        
        
          ),  


        
        
          195
        
                     cvPoint((i + 
        
          1
        
        )*nScale - 
        
          1
        
        , histHeight -
        
           nRealHeight),


        
        
          196
        
        
                      cvScalar(i),   


        
        
          197
        
        
                      CV_FILLED


        
        
          198
        
        
                  );   


        
        
          199
        
        
              }


        
        
          200
        
        
          //
        
        
          cvFillConvexPoly
        
        
          201
        
        
          202
        
             cvReleaseHist(&
        
          pHist);


        
        
          203
        
        
          return
        
        
           pHistImg;


        
        
          204
        
         }
      
View Code

?

一、直方圖均衡化概述

直方圖均衡化是一種圖像增強(qiáng)方法,其基本思想是把給定圖像的直方圖分布改造成均勻分布的直方圖,從而增加象素灰度值的動態(tài)范圍,達(dá)到增強(qiáng)圖像整體對比度的效果。由信息學(xué)的理論來解釋,具有最大熵(信息量)的圖像為均衡化圖像。

直方圖均衡化可表示為: clip_image002 ,t為某個象素變換后的灰度級,s為該象素變換前的灰度級。

該灰度變換函數(shù)應(yīng)滿足如下兩個條件:

1)f(s)在 clip_image004 范圍內(nèi)是單值遞增函數(shù);

2)對 clip_image006

條件1:保證原圖各灰度級在變換后仍保持從黑到白(或從白到黑)的排列順序;

條件2:保證變換前后灰度值動態(tài)范圍的一致性。

可以證明累積分布函數(shù)(cumulative distribution function CDF)滿足上述兩個條件并能將s的分布轉(zhuǎn)換為t的均勻分布。

事實(shí)上,s的CDF就是原始圖的累積直方圖,即:

clip_image008

其中 clip_image010 clip_image012 、k=0,1,…,L-1

根據(jù)這個公式,可以直接算出直方圖均衡化后各象素的灰度值。 clip_image014 需要取整,以滿足數(shù)字圖象的要求。

?

二、算法步驟

步驟

運(yùn)算

1

列出原始圖灰度級 clip_image016

2

統(tǒng)計(jì)原始直方圖各灰度級象素?cái)?shù) clip_image018

3

計(jì)算原始直方圖(像素比例)

4

計(jì)算累積直方圖 clip_image020 (累計(jì)像素比例)

5

取整 clip_image022

6

確定映射對應(yīng)關(guān)系( clip_image016[1] clip_image020[1]

7

計(jì)算新的直方圖

三、算法測試

1、灰度圖

clip_image024 clip_image026

clip_image028

clip_image030

2、彩色圖

clip_image032 clip_image034

clip_image036

clip_image038

?

四、結(jié)果分析

(1)對于灰度圖和彩色圖,算法結(jié)果都不錯,直方圖顯示像素分布很廣、很平均。

(2)直方圖均衡化的優(yōu)點(diǎn):自動增強(qiáng)整個圖像的對比度。

(3)直方圖均衡化的不足:具體增強(qiáng)效果不易控制,處理的結(jié)果總是得到全局均衡化的直方圖。

直方圖均衡化的 C++ 實(shí)現(xiàn)(基于 openCV)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲国产日韩a在线亚洲 | 天天干天天操天天射 | 夜色资源站www国产在线资源 | 久久成人激情视频 | 亚洲综合色婷婷在线观看 | 国产精品久久久久久久免费 | 老子理论不卡影院6080 | 亚洲无总热门 | 狠狠干夜夜 | 国产欧美成人 | 欧美性视频在线激情 | 视频精品一区二区三区 | 四虎成人免费网址在线 | 亚洲国产一区二区三区在线观看 | 中文字幕久久综合 | 九九99九九视频在线观看 | 日韩一区二区不卡中文字幕 | 熊出没之重启未来免费观看 | 精品一区二区三区 不卡高清 | 免费福利在线 | 国产a免费视频 | 久草热久草在线视频 | 久久草草 | 香蕉免费一区二区三区在线观看 | 亚洲精品视频免费观看 | 婷婷色九月 | 亚洲在线小视频 | 中文一级黄色片 | 四虎影视免费永久在线观看 | 免费看a网站 | 国产欧美成人免费观看视频 | 日本一级片在线观看 | 日韩欧美一级毛片在线 | 欧美精品aaa久久久影院 | 真实国产精品视频国产网 | 欧美日韩国产高清精卡 | 激情五月色婷婷在线观看 | 婷婷国产天堂久久综合五月 | 久久有这有精品在线观看 | 国产情侣久久精品 | a一级黄色片|