Debug assertion failed with Open CV SIFT - c++

I hope someone can help. I have been trying to work with SIFT and even the simplest program like this will cause a debug assertion failed.
int DoSift()
{
string image2 ="G:/SIFT Test/Foods/f1.jpg";
string image1 ="G:/SIFT Test/Foods/f2.jpg";
Mat input = imread(image1, IMREAD_GRAYSCALE );
Mat img_2 = imread( image2, IMREAD_GRAYSCALE );
// const cv::Mat input = cv::imread("input.jpg", 0); //Load as grayscale
cv::SiftFeatureDetector detector;
std::vector<cv::KeyPoint> keypoints;
detector.detect(input, keypoints);
// Add results to image and save.
cv::Mat output;
cv::drawKeypoints(input, keypoints, output);`enter code here`
cv::imwrite("sift_result.jpg", output);
return Exit_Success(); //<- it happens here
}
I think it's in the cleanup somewhere here:
void _Tidy()
{ // free all storage
if (this->_Myfirst != pointer())
{ // something to free, destroy and deallocate it
this->_Orphan_all();
_Destroy(this->_Myfirst, this->_Mylast);
this->_Getal().deallocate(this->_Myfirst,
this->_Myend - this->_Myfirst);**//--->......Here.....**
this->_Myfirst = pointer();
this->_Mylast = pointer();
this->_Myend = pointer();
}
The exception details says:
**Debug assertion failed.
Program:...
File: f:\dd\vctools\ctr_bld\self_x86\crt\src\dbgheap.c
Line: 1322
Expression: _CrtIsValidHeapPointers(pUserData)**

The problem is with visual studio 2012. Switching to 2010 ran smoothly. I believe that the 2012 doesn't quite like openCV.

Related

Problems while trying to extract features using SIFT in opencv 4.5.1

I am trying to extract features of an image using SIFT in opencv 4.5.1, but when I try to check the result by using drawKeypoints() I keep getting this cryptic error:
OpenCV(4.5.1) Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in cv::debug_build_guard::_OutputArray::create, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\matrix_wrap.cpp, line 1147
D:\School\IP2\OpenCVApplication-VS2019_OCV451_basic\x64\Debug\OpenCVApplication.exe (process 6140) exited with code -1.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
The problem seems to be with the drawKeypoints() function but I'm not sure what causes the problem.
The function:
vector<KeyPoint> extractFeatures(String path) {
Mat_<uchar> source = imread(path, 0);
Mat_<uchar> output(source.rows, source.cols);
vector<KeyPoint> keypoints;
Ptr<SIFT> sift = SIFT::create();
sift->detect(source, keypoints);
drawKeypoints(source, keypoints, output);
imshow("sift_result", output);
return keypoints;
}
You are getting a exception because output argument of drawKeypoints must be 3 channels colored image, and you are initializing output to 1 channel (grayscale) image.
When using: Mat output(source.rows, source.cols); or Mat output;, the drawKeypoints function creates a new colored matrix automatically.
When using the derived template matrix class Mat_<uchar>, the function drawKeypoints raises an exception!
You may replace: Mat_<uchar> output(source.rows, source.cols); with:
Mat_<Vec3b> output(source.rows, source.cols); //Create 3 color channels image (matrix).
Note:
You may also use Mat instead of Mat_:
Mat output; //The matrix is going to be dynamically allocated inside drawKeypoints function.
Note:
My current OpenCV version (4.2.0) has no SIFT support, so I used ORB instead (for testing).
Here is the code sample used for testing:
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat_<uchar> source = imread("graf.png", 0);
Mat_<Vec3b> output(source.rows, source.cols); //Create 3 color channels image (matrix).
vector<KeyPoint> keypoints;
Ptr<ORB> orb = ORB::create();
orb->detect(source, keypoints);
drawKeypoints(source, keypoints, output);
imshow("orb_result", output);
waitKey(0);
destroyAllWindows();
return 0;
}
Result:

Train SVM and save it with OpenCV 3.0

I am using Visual Studio 2010, with OpenCV 3.0. I'm trying to train a SVM and to save it into a file, but I am having problems.
My purpose is to extract the HOG features of some images and train a SVM with them. All seems to be right, but when I try to save the model in a xml file I obtain the following error:
Unhandled exception in 0x000007fefd9bb16d (KernelBase.dll) in TrainSVM.exe: Exception de MICROSOFT C++: cv::Exception at memory location 0x0026e1b0.
And then this is showed in console:
OpenCV Error: Parsing error (SVM model data is invalid, check sv_count, var_* an
d class_count tags) in cv::ml::SVMImpl::write, file C:\builds\master_PackSlave-w
in64-vc12-shared\opencv\modules\ml\src\svm.cpp, line 2027
The error seems to appear when the SVM has not been trained properly, but I don't understand where I have failed, because the line
svm->train(auxResult)
has "true" as result.
I have checked the images and they are loaded properly, anybody could help me?
Thanks in advance.
Here is the code:
String imagesPathPos = "Positivas/*.jpg"; // it has filters, too !
vector<String> fp;
glob(imagesPathPos, fp);
int tamaƱo = fp.size();
std::vector<cv::Point> positions;
positions.push_back(cv::Point(0,0));
std::vector<float> descriptor;
Ptr<TrainData> auxResult;
for (size_t i=0; i<fp.size(); ++i)
{
string nameFile = fp[i];
Mat img = imread(fp[i]);
cv::Mat grayImg;
cvtColor( img, grayImg, COLOR_BGR2GRAY );
hog.compute(grayImg,descriptor,winStride,trainingPadding,positions);
Mat auxDescriptor = cv::Mat(descriptor);
Mat descriptorMat(1,auxDescriptor.rows,CV_32FC1);
transpose(auxDescriptor, descriptorMat);
trainingData.push_back(descriptorMat);
trainingLabels.push_back(labelPositive);
}
String imagesPathNeg = "Negativas/*.jpg";
vector<String> fn;
glob(imagesPathNeg, fn, true);
for (size_t i=0; i<fn.size(); i++)
{
Mat img = imread(fn[i]);
cv::Mat grayImg;
cvtColor( img, grayImg, COLOR_BGR2GRAY );
hog.compute(grayImg,descriptor,Size(),Size(),positions);
Mat auxDescriptor = cv::Mat(descriptor);
Mat descriptorMat(1,auxDescriptor.rows,CV_32FC1);
transpose(auxDescriptor, descriptorMat);
trainingData.push_back(descriptorMat);
trainingLabels.push_back(labelPositive);
}
auxResult = TrainData::create(trainingData, type, trainingLabels);
svm->train(auxResult);
svm->save("output.xml");
You are defining "labelPositive" even when the images are negative. Possibly the error is there, within the loop through the vector fn:
trainingLabels.push_back(labelPositive);
You should use a parameter named "labelNegative" defined as -1.

BRIEF implementation with OpenCV 2.4.10

Does someone know of the link to BRIEF implementation with OpenCV 2.4? Regards.
PS: I know such questions are generally not welcome on SO, as the primary focus is what work you have done. But there was a similar question which was quite well received.
One of the answers to that questions suggests a generic manner for SIFT, which could be extended to BRIEF. Here is my slightly modified code.
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/highgui/highgui.hpp>
//using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
Mat image = imread("load02.jpg", CV_LOAD_IMAGE_GRAYSCALE);
cv::initModule_nonfree();
// Create smart pointer for SIFT feature detector.
Ptr<FeatureDetector> featureDetector = FeatureDetector::create("HARRIS"); // "BRIEF was initially written. Changed after answer."
vector<KeyPoint> keypoints;
// Detect the keypoints
featureDetector->detect(image, keypoints); // NOTE: featureDetector is a pointer hence the '->'.
//Similarly, we create a smart pointer to the SIFT extractor.
Ptr<DescriptorExtractor> featureExtractor = DescriptorExtractor::create("BRIEF");
// Compute the 128 dimension SIFT descriptor at each keypoint.
// Each row in "descriptors" correspond to the SIFT descriptor for each keypoint
Mat descriptors;
featureExtractor->compute(image, keypoints, descriptors);
// If you would like to draw the detected keypoint just to check
Mat outputImage;
Scalar keypointColor = Scalar(255, 0, 0); // Blue keypoints.
drawKeypoints(image, keypoints, outputImage, keypointColor, DrawMatchesFlags::DEFAULT);
namedWindow("Output");
imshow("Output", outputImage);
char c = ' ';
while ((c = waitKey(0)) != 'q'); // Keep window there until user presses 'q' to quit.
return 0;
}
The issue with this code is that it gives an error: First-chance exception at 0x00007FFB84698B9C in Project2.exe: Microsoft C++ exception: cv::Exception at memory location 0x00000071F4FBF8E0.
The error results in the function execution breaking. A tag says that execution will resume at the namedWindow("Output"); line.
Could someone please help fix this issue, or suggest a new code altogether? Thanks.
EDIT: The terminal now shows an error: Assertion failed (!outImage.empty()) in cv::drawKeypoints, file ..\..\..\..opencv\modules\features2d\src\draw.cpp, line 115. The next statement from where the code will resume remains the same, as drawKepoints is called just before it.
In OpenCV, BRIEF is a DescriptorExtractor, not a FeatureDetector. According to FeatureDetector::create, this factory method does not support "BRIEF" algorithm. In other words, FeatureDetector::create("BRIEF") returns a null pointer and your program crashes.
The general steps in feature matching are:
Find some interesting (feature) points in an image: FeatureDetector
Find a way to describe those points: DescriptorExtractor
Try to match descriptors (feature vectors) in two images: DescriptorMatcher
BRIEF is an algorithm only for step 2. You can use some other methods, HARRIS, ORB, ..., in step 1 and pass the result to step 2 using BRIEF. Besides, SIFT can be used in both step 1 and 2 because the algorithm provides methods for both steps.
Here's a simple example to use BRIEF in OpenCV. First step, find points that looks interesting (key points) in an image:
vector<KeyPoint> DetectKeyPoints(const Mat &image)
{
auto featureDetector = FeatureDetector::create("HARRIS");
vector<KeyPoint> keyPoints;
featureDetector->detect(image, keyPoints);
return keyPoints;
}
You can try any FeatureDetector algorithm instead of "HARRIS". Next step, compute the descriptors from key points:
Mat ComputeDescriptors(const Mat &image, vector<KeyPoint> &keyPoints)
{
auto featureExtractor = DescriptorExtractor::create("BRIEF");
Mat descriptors;
featureExtractor->compute(image, keyPoints, descriptors);
return descriptors;
}
You can use algorithm different than "BRIEF", too. And you can see that the algorithms in DescriptorExtractor is not the same as the algorithms in FeatureDetector. The last step, match two descriptors:
vector<DMatch> MatchTwoImage(const Mat &descriptor1, const Mat &descriptor2)
{
auto matcher = DescriptorMatcher::create("BruteForce");
vector<DMatch> matches;
matcher->match(descriptor1, descriptor2, matches);
return matches;
}
Similarly, you can try different matching algorithm other than "BruteForce". Finally back to main program, you can build the application from those functions:
auto img1 = cv::imread("image1.jpg");
auto img2 = cv::imread("image2.jpg");
auto keyPoints1 = DetectKeyPoints(img1);
auto keyPoints2 = DetectKeyPoints(img2);
auto descriptor1 = ComputeDescriptors(img1, keyPoints1);
auto descriptor2 = ComputeDescriptors(img2, keyPoints2);
auto matches = MatchTwoImage(descriptor1, descriptor2);
and use matches vector to complete your application. If you want to check the results, OpenCV also provides functions to draw results of step 1 & 3 in an image. For example, draw the matches in the final step:
Mat result;
drawMatches(img1, keyPoints1, img2, keyPoints2, matches, result);
imshow("result", result);
waitKey(0);

Debug Assertion Failed Expression: _pFirstBlock == pHead using OpenCV and C++ trying to call SurfFeatureDetector

I have this function in C++ using OpenCV:
vector<KeyPoint> test(Mat img)
{
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
vector<KeyPoint> vKeypoints;
detector.detect( img, vKeypoints );
return vKeypoints;
}
When I call this function in my main-method everything works fine.
int main( int, char** argv )
{
// path to a image-file
char* input = "image.jpg";
// read image into Mat img
Mat img = imread( input, CV_LOAD_IMAGE_GRAYSCALE );
// call function test
test(img);
waitKey(0);
return 0;
}
But as soon as I'm calling this method twice...
int main( int, char** argv )
{
// path to a image-file
char* input = "image.jpg";
// read image into Mat img
Mat img = imread( input, CV_LOAD_IMAGE_GRAYSCALE );
// call function test
test(img);
test(img); // <-- !!! second call
waitKey(0);
return 0;
}
...I get the following error:
Can anyone tell me where my mistake is and how I could fix this? I need to call this function twice with two different images, but every time I do this I get this error.
I'm using Visual Studio 2012.
I've found my mistake. I accidentally copied the openCV-dlls of the VC12 folder, because I forgot that Visual Studio 2012 is VC11. Now it works. Maybe this will help someone else who has the same problem and copied the dlls of the wrong folder.
I also had the same Debug Assertion Failed (dbgheap.c Line:1424 Expression: _pFirstBlock == pHead). I am using Visual Studio 2012 Professional (vc11) to compile with OpenCV 2.4.9.
int main(){
SurfFeatureDetector detector(50);
std::vector<KeyPoint> keypoints[502];
//In my case, some ranges in for-loop may success without Assertion failed.
for(int j=0;j<502;j++){
sprintf(filename, "../../%06d.bmp", j);
img[j] = imread(filename);
detector.detect(img[j], keypoints[j]);
waitKey(10);
}
printf("leaving main()\n");
//Debug Assertion Failed after leaving main()
}
My mistake is that I set the system PATH variable to OpenCV x64 path (c:\opencv\build\x64\vc11\bin) but I linked my code with x86 libs in VC2012 project.
After redefine the PATH variable in Windows to correct OpenCV x86 path (c:\opencv\build\x86\vc11\bin) and restart my VC2012, the Assertion failed of dbgheap.c(1424) will not happened again.
#TheMotivation, Your answer inspired me. Thank you.
It is library problem,in my case changed the project property "Use of mfc" from static to "Use MFC in a Shared DLL" do the trick.

cvExtractSURF throwing exception, incorrect size of input array ( ) in cvCreateSeq

I'm using the following code with OpenCV on a Mac. The following function receives a path to an image file from another function, and that works fine. However, cvExtractSURF throws an exception stating:
OpenCV Error: Incorrect size of input array () in cvCreateSeq, file >/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarb>alls_ports_graphics_opencv/opencv/work/OpenCV-2.4.1/modules/core/src/datastructs.cpp, line 372
terminate called throwing an exception
The code is as follows:
- (int)extractFromImagePath:(NSString*)pathToFile{
[self.statusText setStringValue:#"image received"];
NSLog(#"Path: %#",pathToFile);
// Path: /Users/loco/Desktop/testimage.png
const char * path = [pathToFile UTF8String];
IplImage* image = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE );
cv::Mat im = cv::imread(path,0);
if(im.data == NULL)
{
std::cout<<"Unable to read "<<path<<std::endl;
return 0;
}
/* extract the SURF keypoints/descriptors of an image */
// presumes a previously declared IplImage *image
CvSeq *keypoints = NULL;
CvSeq *descriptors = NULL;
CvMemStorage *storage = cvCreateMemStorage(0);
cvExtractSURF(image, NULL, &keypoints, &descriptors, storage, cvSURFParams(0, 600));
// OpenCV Error: Incorrect size of input array () in cvCreateSeq, file /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_graphics_opencv/opencv/work/OpenCV-2.4.1/modules/core/src/datastructs.cpp, line 372
// terminate called throwing an exception
[self.statusText setStringValue:#"writing to files"];
/* build a path to save a file in the documents directoy */
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *xmlpath_kp = [docs stringByAppendingPathComponent:#"keypoints.xml"];
NSString *xmlpath_desc = [docs stringByAppendingPathComponent:#"descriptors.xml"];
/* serialize to xml and save to disc */
cvSave([xmlpath_kp UTF8String], keypoints);
cvSave([xmlpath_desc UTF8String], descriptors);
[self.statusText setStringValue:#"done"];
/* don't forget your cleanup ;) */
cvReleaseImage(&image);
cvClearMemStorage(storage);
return 1;
}
Would anybody know what's going on? Any help would be appreciated!
I tested part of your code that throwing error.The following code is not giving any error, just check it out.
IplImage* image = cvLoadImage("C:\\Koala.jpg",CV_LOAD_IMAGE_GRAYSCALE);
CvSeq* kp_pns;
CvSeq* desct;
CvSURFParams pams;
pams.hessianThreshold=10;
pams.nOctaveLayers=4;
pams.nOctaves=3;
pams.upright = true;
CvMemStorage *storage = cvCreateMemStorage(0);
cvExtractSURF(image,NULL,&kp_pns,&desct,storage,pams,0);
I am able to extract the surf keypoints without any error. I hope the error will be resolved.
Adjust hessianThreshold for SURF;
from OpenCV they say;
hessianThreshold only features with hessian larger than that are
extracted. good default value is ~300-500 (can depend on the average
local contrast and sharpness of the image). user can further filter
out some features based on their hessian values and other
characteristics.
As Andrey Kamaev pointed out, it was a bug in 2.4.0 & 2.4.1. Upgrading did fix it.