I set up OpenCV with Visual Studio for a project and I am getting these really weird memory errors. I have been searching extensively for a fix to this, and while there are many similar questions, they are either unanswered or not working for me.
This is one of the few OpenCV functions I'm having problems with (got it from docs), which replicates the errors I get:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);
/** #function main */
int main(int argc, char** argv)
{
/// Load source image and convert it to gray
std::string img = "<path-to-picture>";
src = imread(img, CV_LOAD_IMAGE_COLOR);
/// Convert image to gray and blur it
cvtColor(src, src_gray, CV_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
/// Create Window
char* source_window = "Source";
namedWindow(source_window, CV_WINDOW_AUTOSIZE);
imshow(source_window, src);
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny(src_gray, canny_output, thresh, thresh * 2, 3);
/// Find contours
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Draw contours
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}
/// Show in a window
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
imshow("Contours", drawing);
waitKey(0);
return(0);
}
Weird thing is that findContours() works perfectly, but after that the program crashes with this error:
Expression: "(_Ptr_user & (_BIG_ALLOCATION_ALIGNMENT - 1)) == 0" && 0
Any ideas on how to fix this? Here's my OpenCV setup:
Visual Studio 2015, Debug/Release x64
OpenCV 2.4.13 (pre-built)
C++ includes points to build\include
C++ linker points to \build\x64\vc12\lib
Dependencies includes libs in the above folder.
You're using OpenCV build with vc12 compiler (Visual Studio 2013), but in your project you're using vc14 (Visual Studio 2105).
Be sure to use the prebuild libs compiled with vc14.
I'm sure OpenCV 3.1 has prebuild binaries for vc14. I don't know if OpenCV 2.4.13 has them, too (probably not). In this case you need to recompile OpenCV with vc14, or switch to OpenCV 3.1
Related
The following code for finding contours in an image does not give any compilation errors. However, on running I get the error
"Open cv:Assertion failed (size.width > 0 && size.height > 0)" in the OpenCV imshow file.
I tried the code with just the imshow function, removing everything after it, and the code runs fine, hence the file location does not seem to be a problem!
Any help would be much appreciated.
Thanks in advance!
#include <opencv\cv.h>
#include <opencv2\highgui\highgui.hpp>
#include <opencv\cvaux.h>
#include <opencv\cxcore.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
#include <conio.h>
using namespace cv;
using namespace std;
int main() {
Mat img1;
Mat output;
Mat img = imread("blue.jpg");
cvtColor(img, img1, CV_BGR2GRAY);
threshold(img1, output, 176, 255, CV_THRESH_BINARY);
imshow("hi", output);
vector<vector<Point>> Contours;
vector<Vec4i> hier;
Mat final;
findContours(img1, Contours, hier, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
for (int i = 0; i < Contours.size(); i++)
{
drawContours(final, Contours, i, Scalar(0, 255, 0), 1, 8, hier);
}
imshow("result", final);
waitKey();
}
You are drawing to a non initialized matrix (final) here:
Mat final;
....
drawContours(final, Contours, i, Scalar(0, 255, 0), 1, 8, hier);
You should initialize final first, like:
Mat final = img.clone();
I was having issues with OpenCV 2.4.8's "findContours" method. Specifically the following error:
OpenCV Error: Unsupported format or combination of formats ([Start]FindContours support only 8uC1 and 32sC1 images) in cvStartFindContours, file ..\..\..\..\opencv\modules\imgproc\src\contours.cpp, line 196
From the contents of the message it would seem that I am using an inappropriate image format, however I'm pretty sure that my code specifies an 8uC1 (8 bit 1 channel) matrix.
/* Threshold source image (src1 which is a grayscale image) */
Mat threshImg(src1.rows, src1.cols, CV_8UC1);
threshold(src1, threshImg, thresh, 255, CV_THRESH_BINARY);
/* Get contours */
Mat threshCopy = threshImg; // Copying image because findContours method edits image data
std::vector<std::vector<Point>> contours;
findContours(threshCopy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
I am compiling the code on the command line using cl and link as follows:
$: cl NameOfCode.cpp -W2 -EHsc -c -I OpenCVIncludeDirectory
$: link NameOfCode.obj -LIBPATH:OpenCVLibraryDirectory opencv_core248.lib opencv_highgui248.lib opencv_imgproc248.lib
To enable the usage of cl and link I run vsvars32.bat from Visual studio 2010:
$: "C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat"
I'm rewrite your code,I think it fine you can try it.
//Copy the src1 image to threshImg
Mat threshImg = src1.clone();
//Covert the threshImg from 8-channel to 1-channel and threshold it to binary image.
cvtColor(threshImg,threshImg, CV_RGB2GRAY);
threshold(src1, threshImg, thresh, 255, CV_THRESH_BINARY);
//Finnaly you can get a contours.
Mat threshCopy = threshImg.clone;
std::vector<std::vector<Point>> contours;
findContours(threshCopy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
It looks like the problem ended up being Visual Studio related. After installing SP1 http://www.microsoft.com/en-us/download/details.aspx?id=23691 and making adjustments to the code as suggested by berak and vasan. The final code is below:
/* NOTE: Using namespace cv & std */
/* Get input image */
Mat origImg = imread("C:\\PathToImage\\Image.png", CV_LOAD_IMAGE_GRAYSCALE);
/* Threshold input image */
Mat threshImg;
threshold(origImg, threshImg, 150, 255.0, THRESH_BINARY);
/* Get contours from threshold image */
Mat copyImage = threshImg.clone();
vector<vector<Point>> contours;
findContours(copyImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
I am trying to extract and draw contours from an image.
The code I am chosing is mostly taken from the opencv sample code, But When ever I run this code , I got an exception error with message
"First-chance exception at 0x000007FEFDCA9E5D in test1.exe: Microsoft C++ exception: cv::Exception at memory location 0x000000000028EB40.
If there is a handler for this exception, the program may be safely continued."
, I've been looking for a solution but rather I found similar issue .
Is there any solution on following code, because it is most common code if anyone tries to draw contours.
OR I would be very happy with others who are facing same error , if someone put an optimal or common solution for contour extraction
`
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include "opencv2\imgproc\imgproc.hpp"
using namespace cv;
using namespace std;
int main( int argc, const char** argv )
{
Mat img1 = imread("ima1.JPG", CV_LOAD_IMAGE_UNCHANGED);
Mat canny_img1;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
RNG rng(12345);
/*Using canny filter for feature extraction in image 1*/
Canny(img1,canny_img1,1,3,3,0);
/* Find contours*/
findContours( canny_img1 , contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/* Draw contours */
// Mat drawing = Mat::zeros( canny_img1.size(), CV_8UC3 );
/// Draw contours
Mat drawing = Mat::zeros( canny_img1.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
waitKey(0);
return 0;
}
`
For sample codes to run, you need to have your VS project configured correctly.
You can do this: http://docs.opencv.org/doc/tutorials/introduction/windows_visual_studio_Opencv/windows_visual_studio_Opencv.html?highlight=visual%20studio%20installation
Some of the main points:
You have to go to project properties and set some things:
1) use staticlibrary or dynamic : for that you need to select correctly the appropriate directory in "Additional library directory".
Depending upon the mode in which you are trying to run the project "Debug/Release" if you use staticlib you need to add .lib files with "d" in it before extension.
2) Depending upon the 32 bit or 64 bit project which you are making you need to add appropriate dll directory to System Path.
3) You need to add "Include additional directory to "c\opencv\build\include"
Hope it will help
I have been stuck with this issue for days;
I created a Qt console project, connected it with OpenCV and everything was working just fine;
I created a Qt Gui project, added a button and copied the same code from the previous project in the button's slot, I got a windows segFault and program exited with code -1073741819.
So I used the debugger to detect the problem and it turned out to be at the use of function cv::threshold.
I changed it and instead used cv::Canny but then I got the same problem with cv::findContours !
The strange thing is that when I called the button's 'MainWindow::on_pushButton_clicked()'
in the windows' constructor it worked!!!
here's debugger output:
0 cv::thresh_8u(cv::Mat const&, cv::Mat&, unsigned char, unsigned char, int) C:\OpenCV2.4\OpenMinGw\install\bin\libopencv_imgproc240.dll 0 0x62b2c624
1 cv::_InputArray::getMat(int) const C:\OpenCV2.4\OpenMinGw\install\bin\libopencv_core240.dll 0 0x65c1a838
2 ?? 0 0x00000000
and here's the function where I get the error (which I got from OpenCV tutorials):
void MainWindow::on_pushButton_clicked(){
Mat src; Mat src_gray;
int thresh = 100;
RNG rng(12345);
Mat canny_output;
vector<vector<Point> > contours;
/// Load source image and convert it to gray
src = imread( "hat-10.bmp", 1 );
cvtColor( src, src_gray, CV_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
/// Detect edges using canny
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
qDebug("Ok 1");
/// Find contours
if(cv::sum(src_gray).val[0] > 0.0){
qDebug("Ok 2");
cv::findContours( src_gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
/// Draw contours
Mat drawing = Mat::zeros( src_gray.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2);//, 8, hierarchy, 0, Point() );
}
/// Show in a window
imshow( "Contours", drawing);
}
Using:
Windows 7 x64
OpenCV 2.4.0 compiled using mingw 4.1.0
Qt Creator 2.0.0 Based on Qt 4.7.0 (32 bit)
Edit:
here's a shorter version of my code :
void MainWindow::on_toolButton_clicked(){
std::vector<std::vector<cv::Point> > contours;
/// Load source image and convert it to gray
Mat src = imread( "C:/Users/poste/L3 ISIL/PFE Licence/new bmp/hat-10.bmp", 1);
// my image is already a binary one
Mat canny_output(src.size(), src.type());
Canny(src,canny_output,100,200,3);
imshow("Source", canny_output); // here image is displayed before crash
waitKey(500);
/// Find contours
findContours(canny_output, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
}
in console mode, there's no problem. when called from GUI app constructor there's also no problem.
It only crashes when actually clicking on the button.
edit:
I took a screenshot ![here]http://i.stack.imgur.com/1LyeF.png
canny_output was displayed which means image was loaded.
Uploaded project here
First make sure that the image that you want to threshold is really a gray scaled image. Show it in another window after Thresholding.
Do that before cv::FindContours:
cvThreshold(originalImage,resultingImage,100,100,CV_THRESH_BINARY)
also change that:
vector<vector<Point> > contours;
to:
vector<vector<cv::Point2f> > contours;
Try this:
/// Load source image and convert it to gray
Mat src = imread( "hat-10.bmp", 1 );
Mat src_gray(src.size(), CV_8U);
cvtColor( src, src_gray, CV_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
//Apply threshold
cv::Mat thres_output(src_gray.size(), src_gray.type());
cv::threshold(src_gray, thres_output, 100, 255, cv::THRESH_BINARY);
qDebug("Ok 1");
OpenCV docs have a full demo on Basic Thresholding Operations.
EDIT:
After carefully reviewing your code and comments, I think I know what's going on: these problems might be happening because imread() can't access the specified file. This makes the function return an empty Mat. To check if this is the case, simply do:
Mat src = imread( "hat-10.bmp", 1 );
if (src.empty())
{
std::cout << "!!! imread failed to open image\n";
return;
}
The reason why it happens is because Qt Creator builds the .exe of the project in a separate folder, so when the application runs, it tries to load the image from the directory where the .exe was launched, and it fails because the image isn't there.
When calling imread() remember to pass the FULL PATH to the file. See if that fixes the issue.
EDIT:
Remember to convert the image to binary before feeding it to findContours():
// Convert from 32F to 8U
cv::Mat binary_img;
canny_output.convertTo(binary_img, CV_8U);
std::vector<std::vector<cv::Point> > contours;
cv::findContours(binary_img, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
I used function Qtconcurrent::run() and everything started working.
Even though this isn't a permanent (nor a good) solution; this is all I could come up with.
I'm still open to other answers though.
I am trying to write a program to detect contours within an image using OpenCV in the C++ environment.
The problem with it is that I don't get a compile error, but instead a runtime error. I have no idea why; I followed the book and OpenCV documentation sources to build the code below and it should work fine but it doesn't... any ideas on what might be wrong...?
#include "iostream"
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv\ml.h>
#include<opencv\cxcore.h>
#include <iostream>
#include <string>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat)
#include <opencv2/highgui/highgui.hpp> // Video write
using namespace cv;
using namespace std;
Mat image; Mat image_gray; Mat image_gray2; Mat threshold_output;
int thresh=100, max_thresh=255;
int main(int argc, char** argv) {
//Load Image
image =imread("C:/Users/Tomazi/Pictures/Opencv/ayo.bmp");
//Convert Image to gray & blur it
cvtColor( image,
image_gray,
CV_BGR2GRAY );
blur( image_gray,
image_gray2,
Size(3,3) );
//Threshold Gray&Blur Image
threshold(image_gray2,
threshold_output,
thresh,
max_thresh,
THRESH_BINARY);
//2D Container
vector<vector<Point>> contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output,
contours, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_NONE,
Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(),CV_8U,Scalar(255));
drawContours(result,contours,
-1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
//Create Window
char* DisplayWindow = "Source";
namedWindow(DisplayWindow, CV_WINDOW_AUTOSIZE);
imshow(DisplayWindow, contours);
waitKey(0);
return 1;
}
I bet that you are using the MSVC IDE. Anyway, your code has a lot of problems and I've covered most of them on Stackoverflow. Here they go:
Escape the slashes
Code safely and check the return of the calls
How Visual Studio loads files at runtime
I suspect that your problem is that imread() is failing because it didn't found the file. The links above will help you fix that.