2015-11-13 98 views
1

因此,我的後續代碼中的問題是圖像二值化的結果變得太暗。 (甚至有一個示例圖像,我有它的二進制圖像變成全黑色。)CImg:圖像二值化結果失敗

我一直在尋找我的代碼很長一段時間的任何錯誤,並且沒有發現任何看起來似乎對我有問題的東西。

下面是我想二值化圖像:

Image before binarized - in my code is named: "hildebrantmed.bmp"

下面是生成的二進制圖像:

Image after binarized

之前,我告訴你我的源代碼,這裏有「規則'(因爲這是我最近得到的任務):

  1. 我不允許使用CImg以外的任何其他庫。
  2. 要使用的編程語言是C/C++。沒有別的。
  3. 通常,大津的方法是可以選擇的。但是,如果它更好,我可能會被允許使用其他算法。

最後,這裏是我的源代碼:

#include <iostream> 
#include <CImg.h> 

using namespace std; 
using namespace cimg_library; 

/** 
* Generate histogram of the grayscale image 
*/ 
int * generate_histogram(CImg<unsigned char> img) 
{ 
    int histogram[256]; 

    // initialize default values for histogram 
    for (int i = 0; i < 256; i++) 
    { 
     histogram[i] = 0; 
    } 

    // increment intensity for histogram 
    for (int i = 0; i < img.height(); i++) 
    { 
     for (int j = 0; j < img.width(); j++) 
     { 
      int gray_value = img(j, i, 0, 0); 
      histogram[gray_value]++; 
     } 
    } 

    return histogram; 
} 

/** 
* Find threshold value from the grayscale image's histogram 
*/ 
int otsu_threshold(CImg<unsigned char> img) 
{ 
    int * histogram = generate_histogram(img); // image histogram 

    int total = img.width() * img.height(); // total pixels 

    double sum = 0; 

    int i; 
    for (i = 0; i < 256; i++) 
    { 
     sum += i * histogram[i]; 
    } 

    double sumB = 0; 
    int wB = 0; 
    int wF = 0; 

    double var_max = 0; 
    int threshold = 0; 

    for (i = 0; i < 256; i++) 
    { 
     wB += histogram[i]; 
     if (wB == 0) continue; 

     wF = total - wB; 
     if (wF == 0) continue; 

     sumB += (double)(i * histogram[i]); 

     double mB = sumB/wB; 
     double mF = (sum - sumB)/wF; 

     double var_between = (double)wB * (double)wF * (mB - mF) * (mB - mF); 

     if (var_between > var_max) 
     { 
      var_max = var_between; 
      threshold = i; 
     } 
    } 

    return threshold; 
} 

/** 
* Main function 
*/ 
int main(int argc, char * argv[]) 
{ 
    // retrieve image from its path 
    CImg<unsigned char> img("hildebrantmed.bmp"); 

    const int width = img.width(); 
    const int height = img.height(); 

    // initialize a new image for img's grayscale 
    CImg<unsigned char> gray_img(width, height, 1, 1, 0); 

    // from RGB divided into three separate channels 
    CImg<unsigned char> imgR(width, height, 1, 3, 0); 
    CImg<unsigned char> imgG(width, height, 1, 3, 0); 
    CImg<unsigned char> imgB(width, height, 1, 3, 0); 

    // for all (x, y) pixels in image 
    cimg_forXY(img, x, y) 
    { 
     imgR(x, y, 0, 0) = img(x, y, 0, 0), 
     imgG(x, y, 0, 1) = img(x, y, 0, 1), 
     imgB(x, y, 0, 2) = img(x, y, 0, 2); 

     // separate the channels 
     int R = (int)img(x, y, 0, 0); 
     int G = (int)img(x, y, 0, 1); 
     int B = (int)img(x, y, 0, 2); 

     // obtain gray value from different weights of RGB channels 
     int gray_value = (int)(0.299 * R + 0.587 * G + 0.114 * B); 
     gray_img(x, y, 0, 0) = gray_value; 
    } 

    // find threshold of grayscale image 
    int threshold = otsu_threshold(gray_img); 

    // initialize a binary image version of img 
    CImg<unsigned char> binary_img(width, height, 1, 1, 0); 

    // for every (x, y) pixel in gray_img 
    cimg_forXY(img, x, y) 
    { 
     int gray_value = gray_img(x, y, 0, 0); 

     // COMPARE gray_value with threshold 
     int binary_value; 

     // gray_value > threshold: 255 (white) 
     if (gray_value > threshold) binary_value = 255; 
     // gray_value < threshold: 0 (black) 
     else binary_value = 0; 

     // assign binary_value to each of binary_img's pixels 
     binary_img(x, y, 0, 0) = binary_value; 
    } 

    // display the images 
    CImgDisplay src_disp(img, "Source image"); 
    CImgDisplay gray_disp(gray_img, "Grayscale image"); 
    CImgDisplay binary_disp(binary_img, "Binary image"); 

    while (!src_disp.is_closed() && !gray_disp.is_closed() && !binary_disp.is_closed()) 
    { 
     src_disp.wait(); 
     gray_disp.wait(); 
    } 

    return 0; 
} 

如果您發現其他算法會更好地工作,請在你的答案算法和源代碼提供。感謝您的關注。

回答

0

第一個錯誤:您正在嘗試return數組的指針,該指針在generate_histogram函數結束後實際上會被銷燬。 爲了使其正常工作,你應該提供的指針從調用功能的陣列,像:

{ 
//[....] 
int histogram[256]; 
generate_histogram(img, histogram); 
//[....] 
} 

int * generate_histogram(CImg<unsigned char> img, int* arHistogram) 
{ 
//[....] 
} 
+0

謝謝你這麼多。它最終運作!難怪一個指針的問題可以顯着改變圖片... –

+0

很高興我可以幫助,我自己仍然是一個低級學習者。 –