Ask Your Question
1

Results stability given by adaptiveThreshold with ADAPTIVE_THRESH_GAUSSIAN_C

asked 2015-06-05 04:54:01 -0600

LBerger gravatar image

Hi,

Adaptivethreshold thresh image relative to the difference between image and a blur image. Blur image is given by a boxfilter (APTIVE_THRESH_MEAN_C) or a gaussian filter (ADAPTIVE_THRESH_GAUSSIAN_C) (line 1332 thresh.cpp). When I use adaptiveThreshold with APTIVE_THRESH_MEAN_C results are stable with various filer size. When I use adaptiveThreshold with APTIVE_THRESH_GAUSSIAN_C results are not stable. homogenous region can be white or black. For example size =9 and 11 give with image in this post image descriptionimage description

sigma for gaussian blur is given by this ((size-1)0.5 - 1)0.3 + 0.8. I have try with sigma equal to 200000 filter is flat but problem is still here. So I do not understand if somebody can give me an explanation about this.

Thanks in advance

int main (int argc,char **argv)
{
Mat m,im;
char tmp[256];

m=imread("T4wsOW8.jpg",CV_LOAD_IMAGE_GRAYSCALE);

Mat g=cv::getGaussianKernel( 40, 20000, CV_64F );
// Only to check
for (int i=0;i<g.rows;i++)
    {
    for (int j=0;j<g.cols;j++)
        cout<< g.at<double>(i,j)<<"\t";
    cout<<"\n********\n";
    }
int n=55;
for (int i=5;i<n;i+=2)
    {
    adaptiveThreshold( m, im, 255,cv::ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,i,0);
    sprintf(tmp,"adaThreshGau%d.jpg",i);
    String s(tmp);
    imwrite(s,im);
    }

for (int i=5;i<n;i+=2)
    {
    adaptiveThreshold( m, im, 255,cv::ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,i,0);
    sprintf(tmp,"adaThreshMean%d.jpg",i);
    String s(tmp);
    imwrite(s,im);
    }

return 0;
};
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2015-06-07 13:40:06 -0600

LBerger gravatar image

updated 2015-06-08 04:14:10 -0600

I have found the problem. In adaptiveThreshold gaussianBlur is calculated using image CV_8UC1. That is the problem I think. I think that rounding number add white noise to result image and hence result stability is low.

You can verify with this program. I make a gaussian blur with very big sigma . Gaussian filter is equivalent to a box filter. With a gaussian blur calculated with an image CV_8UC gaussain blur is not at all equivalent to a boxfilter.

With a gaussian blur calculated with an image CV_32FC gaussain blur is now equivalent to a boxfilter.

I think that parameter ADAPTIVE_THRESH_GAUSSIAN_C should be used with caution in adaptiveThreshold

int main (int argc,char **argv)
{
double minVal, maxVal;
int minIdx[2], maxIdx[2];
bool checkKernel = false;

Mat m,imG,imB;
char tmp[256];
int n=55;

m=imread("T4wsOW8.jpg",CV_LOAD_IMAGE_GRAYSCALE);
Mat mF(m.rows, m.cols, CV_32FC1);
for (int i = 0; i<m.rows; i++)
{
    for (int j = 0; j<m.cols; j++)
        mF.at<float>(i, j) = m.at<unsigned char>(i, j);
}

cout << "Image size : Rows = "<<m.rows << "\tcols = " << m.cols << "\t #pixels = "<<m.rows*m.cols<<endl;
for (int blockSize = 3; blockSize < n; blockSize+=2)
{
    cout << "\n********\n";
    if (checkKernel)
    {
        Mat g = cv::getGaussianKernel(blockSize, 1000000, CV_64F);
        cout << blockSize << "\t" << 1.0 / blockSize << endl;
        for (int i = 0; i<g.rows; i++)
        {
            for (int j = 0; j<g.cols; j++)
                cout << g.at<double>(i, j) << "\t";
        }
        cout << "\n";
    }
    boxFilter(m, imB, CV_32F, Size(blockSize, blockSize),
        Point(-1, -1), true, BORDER_REPLICATE);
    cv::GaussianBlur(m, imG, Size(blockSize, blockSize), 1000000.0, 1000000.0, BORDER_REPLICATE);
    Mat imDiff;
    subtract(imG, imB, imDiff, noArray(), CV_32SC1);

    sprintf(tmp, "Diff%d.jpg", blockSize);
    String s(tmp);
    imwrite(s, imDiff);
    Mat a = abs(imDiff);
    Scalar x=sum(a);
    cout << "For CV_8UC (unsigned char) imageBlocksize = " <<blockSize << "\t" << "Sum( abs(Gaussian filter -boxFilter)) = "<<x[0] << endl;
    minMaxIdx(imDiff, &minVal, &maxVal,minIdx,maxIdx);
    cout << "Extremum (Gaussian filter -boxFilter) Min = " << minVal << "\tmaxVal = "<<maxVal << endl;
    cv::GaussianBlur(mF, imG, Size(blockSize, blockSize), 1000000.0, 1000000.0, BORDER_REPLICATE);
    subtract(imG, imB, imDiff, noArray(), CV_32SC1);

    a = abs(imDiff);
    x = sum(a);
    cout << "For CV_32F (float) image " << blockSize << "\t" << "Sum( abs(Gaussian filter -boxFilter)) = " << x[0] << endl;
    minMaxIdx(imDiff, &minVal, &maxVal, minIdx, maxIdx);
    cout << "Extremum (Gaussian filter -boxFilter) Min = " << minVal << "\tmaxVal = " << maxVal << endl;

}
return 0;
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-06-05 04:54:01 -0600

Seen: 933 times

Last updated: Jun 08 '15