Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

@matman, Thanks for the attention to this.

OK, you asked, twice, so I'm posting in some ugly code (below).

I think something must be wrong with how I'm passing data to the functions. Again, I know global variables are discouraged but that is what is used in the tutorials. My target image is attached Hot_slab_crop.jpg.

There is a global declaration of Mat src, line 29. This is used to find the proper dimensions for a new Mat inside main at line 58 (works fine) and again inside on_trackbar at line 87 (no good).

Debugging, up to the point where on_trackbar is called (line 80 in main), src.rows and src.cols have good values. Once execution jumps to the on_trackbar function those both go to zero. That is what trips the assert statement in the adaptive threshold code and is doing similar damage here.

/*****************************************************************************************
Contours detection scratch

Load a color image, extract single channel, binarize and find contours.
******************************************************************************************/

#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>

#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

/// Global variables


int threshold_value = 0;
int const threshold_max_value = 200;
int const max_BINARY_value = 255;


/** General variables */
Mat src, src_grn, binarized;

const char* default_file_name = "D:\\TEMP\\Test_Images\\Hot_slab_crop.jpg";//use "D:\\blah" or debug options.

const int w = 500;
int levels = 3;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;


/// Function Headers
static void on_trackbar(int, void*);
void ThresholdBySigma(Mat& source);

/**
* @function main
*/
int main(int argc, char** argv)
{
    /// Read the image
    const char* filename = argc >= 2 ? argv[1] : default_file_name; //use CL filename if any, otherwise default
    Mat src = imread(filename, IMREAD_COLOR); //Read.  IMREAD_COLOR = 1, IMREAD_GRAYSCALE = 0
if (src.empty()) //if no data...help
{
    return -1;
}

//extract green
Mat src_grn = Mat::zeros(src.rows, src.cols, CV_8UC1); //green channel from src
int from_to[] = { 1, 0 }; //copy green channel only (assume BGR)
mixChannels(&src, 1, &src_grn, 1, from_to, 1);

namedWindow("Source_green", 0); //show source image 
imshow("Source_green", src_grn);

ThresholdBySigma(src_grn);// find target area.  Only CV_8UC1 supported.
namedWindow("Threshold at 2 sigma", 0);
imshow("Threshold at 2 sigma", binarized);


//Extract the contours so that
vector<vector<Point> > contours0;
findContours(binarized, contours0, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
contours.resize(contours0.size());
for (size_t k = 0; k < contours0.size(); k++)
    approxPolyDP(Mat(contours0[k]), contours[k], 3, true);


namedWindow("contours", WINDOW_NORMAL);
createTrackbar("levels+3", "contours", &levels, 7, on_trackbar);


on_trackbar(0, 0);
    waitKey();
    return 0;
}

static void on_trackbar(int, void*)
{
    Mat cnt_img = Mat::zeros(src.rows, src.cols, CV_8UC3); //Originally used fixed size, w, at 500
    int _levels = levels - 3;
    drawContours(cnt_img, contours, _levels <= 0 ? 3 : -1, Scalar(128, 255, 255),
        3, LINE_AA, hierarchy, std::abs(_levels));
    imshow("contours", cnt_img);

}


void ThresholdBySigma(Mat& source){

    //cout << "source.type" << source.type << endl; //wrap an assert around this, only CV_8UC1 is supported
Scalar mean;
Scalar stddev;

meanStdDev(source, mean, stddev);
int mean_pxl = int(mean.val[0]);
int stddev_pxl = int(stddev.val[0]);

int threshold_type = 0;
int threshold_value = 0;

threshold_value = mean_pxl + stddev_pxl * 2;
threshold(source, binarized, threshold_value, max_BINARY_value, threshold_type);
//namedWindow("Threshold at 2 sigma", 0);

    //imshow("Threshold at 2 sigma", binarized);

}

@matman, Thanks for the attention to this.

OK, you asked, twice, EDIT - problem was, I redefined "src" in main so I'm posting the global variable used in some ugly code (below).other functions was still blank (hangs head in newbie shame).

I think something must be wrong with how I'm passing data to deleting the functions. Again, I know global variables are discouraged but that is what is used in the tutorials. My target image is attached Hot_slab_crop.jpg.rest of this...

There is a global declaration of Mat src, line 29. This is used to find the proper dimensions for a new Mat inside main at line 58 (works fine) and again inside on_trackbar at line 87 (no good). Thanks.

Debugging, up to the point where on_trackbar is called (line 80 in main), src.rows and src.cols have good values. Once execution jumps to the on_trackbar function those both go to zero. That is what trips the assert statement in the adaptive threshold code and is doing similar damage here.

/*****************************************************************************************
Contours detection scratch

Load a color image, extract single channel, binarize and find contours.
******************************************************************************************/

#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>

#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

/// Global variables


int threshold_value = 0;
int const threshold_max_value = 200;
int const max_BINARY_value = 255;


/** General variables */
Mat src, src_grn, binarized;

const char* default_file_name = "D:\\TEMP\\Test_Images\\Hot_slab_crop.jpg";//use "D:\\blah" or debug options.

const int w = 500;
int levels = 3;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;


/// Function Headers
static void on_trackbar(int, void*);
void ThresholdBySigma(Mat& source);

/**
* @function main
*/
int main(int argc, char** argv)
{
    /// Read the image
    const char* filename = argc >= 2 ? argv[1] : default_file_name; //use CL filename if any, otherwise default
    Mat src = imread(filename, IMREAD_COLOR); //Read.  IMREAD_COLOR = 1, IMREAD_GRAYSCALE = 0
if (src.empty()) //if no data...help
{
    return -1;
}

//extract green
Mat src_grn = Mat::zeros(src.rows, src.cols, CV_8UC1); //green channel from src
int from_to[] = { 1, 0 }; //copy green channel only (assume BGR)
mixChannels(&src, 1, &src_grn, 1, from_to, 1);

namedWindow("Source_green", 0); //show source image 
imshow("Source_green", src_grn);

ThresholdBySigma(src_grn);// find target area.  Only CV_8UC1 supported.
namedWindow("Threshold at 2 sigma", 0);
imshow("Threshold at 2 sigma", binarized);


//Extract the contours so that
vector<vector<Point> > contours0;
findContours(binarized, contours0, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
contours.resize(contours0.size());
for (size_t k = 0; k < contours0.size(); k++)
    approxPolyDP(Mat(contours0[k]), contours[k], 3, true);


namedWindow("contours", WINDOW_NORMAL);
createTrackbar("levels+3", "contours", &levels, 7, on_trackbar);


on_trackbar(0, 0);
    waitKey();
    return 0;
}

static void on_trackbar(int, void*)
{
    Mat cnt_img = Mat::zeros(src.rows, src.cols, CV_8UC3); //Originally used fixed size, w, at 500
    int _levels = levels - 3;
    drawContours(cnt_img, contours, _levels <= 0 ? 3 : -1, Scalar(128, 255, 255),
        3, LINE_AA, hierarchy, std::abs(_levels));
    imshow("contours", cnt_img);

}


void ThresholdBySigma(Mat& source){

    //cout << "source.type" << source.type << endl; //wrap an assert around this, only CV_8UC1 is supported
Scalar mean;
Scalar stddev;

meanStdDev(source, mean, stddev);
int mean_pxl = int(mean.val[0]);
int stddev_pxl = int(stddev.val[0]);

int threshold_type = 0;
int threshold_value = 0;

threshold_value = mean_pxl + stddev_pxl * 2;
threshold(source, binarized, threshold_value, max_BINARY_value, threshold_type);
//namedWindow("Threshold at 2 sigma", 0);

    //imshow("Threshold at 2 sigma", binarized);

}