otsu
C
code posted
created at 05 Jan 11:39
Edit
|
Back
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
//---------------------------------------------------------- // binarisation otsu //---------------------------------------------------------- #include "iostream" #include "stdio.h" #include "stdlib.h" #include "math.h" #include "time.h" #include "cxcore.h" #include "cv.h" #include "highgui.h" int GRAYLEVEL = 256; #define MAX_BRIGHTNESS 255 //const double INFO_THRESHOLD = 0.2; using namespace std; //---------------------------------------------------------- // binarization by Otsu's method // based on maximization of inter-class variance //---------------------------------------------------------- void binarize_otsu(IplImage* image, IplImage* imgBin ) { int hist[GRAYLEVEL]; double prob[GRAYLEVEL], omega[GRAYLEVEL]; // prob of graylevels double myu[GRAYLEVEL]; // mean value for separation double max_sigma, sigma[GRAYLEVEL]; // inter-class variance int i, x, y; /* Loop variable */ int threshold; /* threshold for binarization */ // Histogram generation memset((int*) hist , 0, GRAYLEVEL * sizeof(int) ); CvSize size = cvGetSize(image); for (int i = 0; i < size.height; ++i) { unsigned char* pData = (unsigned char*) (image->imageData + i * image->widthStep); for (int j = 0; j < size.width; ++j) { int k = (int)((unsigned char) *(pData+j)); hist[k]++; } } int taille = size.width * size.height; // calculation of probability density for ( i = 0; i < GRAYLEVEL; ++i ) { prob[i] = (double) ((double)hist[i] / (double)taille); } /* int LEVEL = GRAYLEVEL; double sumProb = 0.0; for ( i = 0; i < GRAYLEVEL; ++i ) { sumProb += prob[i]; if ( sumProb > INFO_THRESHOLD) { LEVEL = i; break; } } GRAYLEVEL = LEVEL; */ // omega & myu generation omega[0] = prob[0]; myu[0] = 0.0; for (i = 1; i < GRAYLEVEL; i++) { omega[i] = omega[i-1] + prob[i]; myu[i] = myu[i-1] + (i*prob[i]); } //---------------------------------------------------------- // sigma maximization // sigma stands for inter-class variance // and determines optimal threshold value //---------------------------------------------------------- threshold = 0; max_sigma = 0.0; for (i = 0; i < GRAYLEVEL-1; i++) { if (omega[i] != 0.0 && omega[i] != 1.0) { //sigma[i] = (omega[i]*(1.0 - omega[i])) * ((myu[GRAYLEVEL-1] - 2*myu[i]) * (myu[GRAYLEVEL-1] - 2*myu[i])); sigma[i] = ((myu[GRAYLEVEL-1]*omega[i] - myu[i]) * (myu[GRAYLEVEL-1]*omega[i] - myu[i])) / (omega[i]*(1.0 - omega[i])); } else { sigma[i] = 0.0; } if (sigma[i] > max_sigma) { max_sigma = sigma[i]; threshold = i; } } printf("threshold = %d\n", threshold); // binarization output into imgBin for (y = 0; y < size.height; ++y) { unsigned char* pData = (unsigned char*) (image->imageData + (y * image->widthStep)); unsigned char* pDataBin = (unsigned char*) (imgBin->imageData + (y * imgBin->widthStep)); for (x = 0; x < size.width; ++x) { if ( *(pData+x) > threshold) { *(pDataBin+x) = MAX_BRIGHTNESS; } else { *(pDataBin+x) = 0; } } } } int main(int argc, char* argv[] ) { IplImage* image = 0; IplImage* imgBin = 0; clock_t start = clock(); (argc == 3) ? image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE) : cout < < "Usage :\n" << argv[0] << " [srcImagePath] [dstimagepath]" < < endl; if ( image != NULL ) { imgBin = cvCloneImage(image); binarize_otsu(image,imgBin ); cvSaveImage(argv[2], imgBin); cvReleaseImage(&image); cvReleaseImage(&imgBin); clock_t end = clock(); double delay = double((double)(end - start) / CLOCKS_PER_SEC); printf("processing time : %lf seconds\n",delay); return EXIT_SUCCESS; } return EXIT_FAILURE; } |
3.54 KB in 5 ms with coderay