2014年3月26日 星期三

Digital Image Processing#2 - 直方圖均化(Histogram Equalization) 與 索貝爾算子(Sobel Operators)

文章流程:
  • 影像成果分析
  • 實作參考整理
  • 三言兩語心得


又是蕾娜?! 狗血評測文

以下為老師範例的LennaGray.bmp,解析度512 x 512,等等找個更正的......


沒有回應,就像一張原圖

原圖(蕾娜)的直方圖分布


隱隱約約的是間隔,恩,不要懷疑,這是張直方圖
還沒做均化之前,可看出明顯的高峰與低谷

歷經社會歷練的Histogram Equalization(均化)


均化之後,整體顏色變豐厚的感覺。蕾娜出社會十年後,令人不勝唏噓

Histogram Equalization的直方圖分布

這張圖與綠色分布圖對比,可以明顯看出波形被拉平,均勻的分散
音樂播放器,頻譜分析顯示,到底對使用者有甚麼用呢 ... ?

戰慄風的Sobel Operator


因為沒有先做濾波處理,所以Sobel後,會看到大量的雜訊
失落二十年的蕾娜,社會寫實風,輪廓描繪得深沉,充分反映當時人們的心聲

實作筆記整理(主要OpenCV Tutorial)

Histogram Equalization

  // 想像: 直方圖是 由下點 與 上點 連接的直線,
  // 視窗程式的原點(0,0)在左上角, 下點就是 Point(第幾個顏色 width, 視窗 height)

  // Draw for each channel, 畫直方圖的迴圈, 同時畫Src直方圖 與 Heq直方圖
  for( int i = 0; i < histSize; i++ )
  {
      line( histSrcImage, Point( bin_w*(i), hist_h) ,
                       Point( bin_w*(i), hist_h - cvRound(src_hist.at(i)) ),
                       Scalar( 0, 255, 0), 2, 8, 0  );
      line( histHeqImage, Point( bin_w*(i), hist_h) ,
                       Point( bin_w*(i), hist_h - cvRound(heq_hist.at(i)) ),
                       Scalar( 0, 0, 255), 2, 8, 0  );
  }

Sobel Operator

  // Padding
  copyMakeBorder(matSrc,matPadd,ypadd,xpadd,ypadd,xpadd,BORDER_CONSTANT, Scalar(0, 0, 0));

  // ...省略...

  // 開始處理pixel, 9宮格矩陣乘入, 注意這邊是Padding過的Src
  for (int y = 1; y < iHiehgtSrc - 1; ++y)  
  {  
    for (int x = 1; x < iWidthSrc - 1; ++x)  
    {  
      // X Sobel計算, {-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0};
      int xSobel = *(dataPadd + (y-1)*stepPadd + x+1)
        + *(dataPadd + y*stepPadd + x+1) * 2
        + *(dataPadd + (y+1)*stepPadd + x+1)
        - *(dataPadd + (y-1)*stepPadd + x-1) 
        - *(dataPadd + y*stepPadd + x-1) * 2 
        - *(dataPadd + (y+1)*stepPadd + x-1);
      // Y Sobel計算, {1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0};
      int ySobel = *(dataPadd + (y-1)*stepPadd + x-1)
        + *(dataPadd + (y-1)*stepPadd + x) * 2
        + *(dataPadd + (y-1)*stepPadd + x+1) 
        - *(dataPadd + (y+1)*stepPadd + x-1)
        - *(dataPadd + (y+1)*stepPadd + x) * 2
        - *(dataPadd + (y+1)*stepPadd + x+1);
      // xSobel與ySobel平方後, 再開根號, 注意, 計算的值不能超過255, 合法區間0 ~ 255
      *(dataDst+ y*stepDst - ypadd*stepDst + x - xpadd) = min(255, cvFloor(sqrt(xSobel*xSobel + ySobel*ySobel))); 

      //測試, (int) / cvFloor / cvRound差異微小
    }  
  }

    二行5句的心得

    太投入最近發生的社會大事了,容我花點時間補完
    眼見不一定為真,影像處理挺有趣的,如果數學有學好的話......

    沒有留言:

    張貼留言