1. 程式人生 > >opencv——最大閾值分割

opencv——最大閾值分割

opencv1.0版本

#include "stdio.h"  
#include "cv.h"  
#include "highgui.h"  
#include "Math.h"
int Otsu(IplImage* src);


int main(int argc, char*argv[])
{
    IplImage* img = cvLoadImage("D:\\chengxu\\opencv\\Desert.jpg", 0);
    IplImage* dst = cvCreateImage(cvGetSize(img), 8, 1);
    int threshold = Otsu(img);
    printf("threshold = %d\n"
, threshold); cvThreshold(img, dst, threshold, 255, CV_THRESH_BINARY); cvNamedWindow("img", 1); cvShowImage("img", dst); cvWaitKey(-1); cvReleaseImage(&img); cvReleaseImage(&dst); cvDestroyWindow("dst"); return 0; } int Otsu(IplImage* src) { int height = src->height; int
width = src->width; //histogram float histogram[256] = { 0 }; for (int i = 0; i < height; i++) { unsigned char* p = (unsigned char*)src->imageData + src->widthStep * i; for (int j = 0; j < width; j++) { histogram[*p++]++; } } //normalize histogram
int size = height * width; for (int i = 0; i < 256; i++) { histogram[i] = histogram[i] / size; } //average pixel value float avgValue = 0; for (int i = 0; i < 256; i++) { avgValue += i * histogram[i]; //整幅影象的平均灰度 } int threshold; float maxVariance = 0; float w = 0, u = 0; for (int i = 0; i < 256; i++) { w += histogram[i]; //假設當前灰度i為閾值, 0~i 灰度的畫素(假設畫素值在此範圍的畫素叫做前景畫素) 所佔整幅影象的比例 u += i * histogram[i]; // 灰度i 之前的畫素(0~i)的平均灰度值: 前景畫素的平均灰度值 float t = avgValue * w - u; float variance = t * t / (w * (1 - w)); if (variance > maxVariance) { maxVariance = variance; threshold = i; } } return threshold; }

opencv2.0版本

#include<opencv2/opencv.hpp>
#include"cv.h"
#include"highgui.h"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
using namespace std;

int otsu(const Mat &img)//最大類間方差閾值分割
{
    float histogram[256] = { 0 };
    for (int i = 0; i<img.rows; i++)
    {
        const unsigned char* p = (const unsigned char*)img.ptr(i);
        for (int j = 0; j<img.cols; j++)
        {
            histogram[p[j]]++;
        }
    }

    float avgValue = 0;
    int numPixel = img.cols*img.rows;
    for (int i = 0; i<256; i++)
    {
        histogram[i] = histogram[i] / numPixel;
        avgValue += i*histogram[i];
    }

    int threshold = 0;
    float gmax = 0;
    float wk = 0, uk = 0;
    for (int i = 0; i<256; i++) {

        wk += histogram[i];
        uk += i*histogram[i];

        float ut = avgValue*wk - uk;
        float g = ut*ut / (wk*(1 - wk));

        if (g > gmax)
        {
            gmax = g;
            threshold = i;
        }
    }
    return threshold;
}
int main( int, char** argv )
{
    Mat src,gray;
    int width = 0;
    int height = 0;
    int channels = 0;
    const char* window_name = "erzhitu";
    src = imread("C:\\Program Files (x86)\\MesaImaging\\Swissranger\\matlab\\swissranger\\xx.jpg");
    if (src.empty())
    {
        return -1;
    }
    width = src.cols;//求影象的行列及通道
    height = src.rows;
    channels = src.channels();
    cvtColor(new_src, gray, CV_BGR2GRAY);//灰度化

    int gray_threshold = 0;//閾值分割
    gray_threshold = otsu(gray);

    cout << gray_threshold << endl;
    Mat erzhitu;
    threshold(gray, erzhitu, gray_threshold, 255,1);
    namedWindow(window_name, WINDOW_AUTOSIZE);
    imshow(window_name, erzhitu);