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);
}
2 | No.2 Revision |
@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);
}