Exception thrown writing to InputOutputArray - c++

I'm trying to test some motion estimation in Visual Studio 2013, using OpenCV v3.0 (which is probably my 1st mistake!). I got an unhandled exception trying to use createOptFlow_DualTVL1() and createOptFlow_Farneback(), and then, for testing, tried cv::accumulate(), which threw the same exception.
It seems that OpenCV can't write to the Mat object that I'm passing these functions. I can't read the actual cvException because I don't have the PDB files, because I didn't compile this version myself. That might be my next stop, but before I do I figured I'd see if anyone's seen this behaviour before.
Here's a minimal working example:
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/tracking.hpp>
#include <opencv2/videoio/videoio.hpp>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
using namespace cv;
int main(int argc, const char** argv)
{
VideoCapture captureDevice;
std::string videoname = "example.mp4";
captureDevice.open(videoname);
//setup image files used in the capture process
Mat currFrame, dst;
captureDevice >> currFrame;
accumulate(currFrame, dst, cv::noArray());
imshow("outputCapture", dst);
//pause for 33ms
waitKey(33);
return 0;
}

dst should be of same size as that currFrame and of type CV_32FC3.
So, add this line of code before calling accumulate -
dst.create(currFrame.size(), CV_32FC3);
Since dst is of float type, you will need to convert it to uchar to display it. For that, convert as shown below -
Mat dst_disp;
dst.convertTo(dst_disp, CV_8UC3);
imshow("outputCapture",dst_disp );
Additionally, as you accumulate more frames in dst, you will need to normalize by number of frames(let's say N) cached in dst. Simply, divide dst by the N, then convert the result into CV_8UC3 and display. For example, if you accumulated 1000 frames in dst do as shown below,
// Accumulate 1000 frames
for(int i = 0; i < 1000; i++)
accumulate(currFrame, dst, cv::noArray());
// Normalize
dst = dst/ 1000;
// Display the frame
Mat dst_disp;
dst.convertTo(dst_disp, CV_8UC3);
imshow("outputCapture",dst_disp );
else, you might get an all white image.
UPDATE
From #berak's comment below.
For normalization, simply use
dst.convert(dst_disp, CV_8UC3, 1.0/N);
where N in example above will be 1000.

Related

Background subtraction in OpenCV

I am trying to implement background subtraction in OpenCV 2.4.10 using mog2. My aim is to segment the hand using background subtraction. Unfortunately, the first frame that is used as foreground appear to be stuck during live capture from the webcam. Here is the code that I used for this simple project
#include "stdafx.h"
#include <opencv2\opencv.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\video\video.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
#include <sstream>
#include <string.h>
using namespace cv;
int main()
{
Mat frame, mask, gray;
BackgroundSubtractorMOG2 mog2;
VideoCapture cap(0);
if (cap.isOpened()){
while (true)
{
if (cap.read(frame))
{
imshow("frame", frame);
cvtColor(frame, gray, cv::COLOR_RGB2GRAY);
imshow("gray", gray);
mog2(gray, mask, 0.0);// 0.1 is learning rate
imshow("Background Subtraction", mask);
if (waitKey(30) >= 0)
break;
}
}
}
cap.release();
return 0;
}
Here is the output
This is because your fist happens to be in the very first frame, thus when you move your hand, you get 2 difference images- one from the new position of your palm, and the other from the old location of the fist, now occupied by the actual background behind it.
I would suggest that you shouldn't have your hand in the first frames

Assertion failed with cv::merge

I am currently doing some C++ image processing with openCV. I developed the application on a Mac with Xcode 6.3.2 and it works perfectly in both debug and release. In order to have a Windows executable program, I am now working on Windows with Visual Studio Express 2013. The program is running well on debug mode but crashes in release mode on this part of the code :
#include "stdafx.h"
#include "math.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/photo/photo.hpp"
#include "opencv2/features2d/features2d.hpp"
using namespace cv;
using namespace std;
int main(int argc, const char** argv)
{
vector<Mat> stacked_images;
Mat medianr_eq, mediang_eq, medianb_eq, objrgb;
medianr_eq = imread("C:\\Path\\medianr_eq.png", CV_LOAD_IMAGE_GRAYSCALE);
mediang_eq = imread("C:\\Path\\mediang_eq.png", CV_LOAD_IMAGE_GRAYSCALE);
medianb_eq = imread("C:\\Path\\medianb_eq.png", CV_LOAD_IMAGE_GRAYSCALE);
objrgb = Mat(medianr_eq.size(), CV_16UC3);
stacked_images.clear();
stacked_images.push_back(medianb_eq); /*B*/
stacked_images.push_back(mediang_eq); /*G*/
stacked_images.push_back(medianr_eq); /*R*/
merge(stacked_images, objrgb);
}
The error I get is :
OpenCV Error : Assertion failed <mv && n > 0> in cv::merge, file C:\builds\master_PackSlave_Win64-vc12-shared\opencv\modules\core\src\convert.cpp, line 941
I can't see where I could have done something wrong... Indeed, it is pretty basic OpenCV !
The images I used are downloadable with this link : https://transfert.u-psud.fr/gs67
For astronomy lovers it is the Stephan's Quintet, taken with Calar Alto Observatory's 1.23m telescope where I currently am an intern.
Thank you in advance for your help,
Arnaud.
I recently had the exact same error, appearing with a valid openCV code running perfectly fine in debug mode but not in release mode.
Looking into the openCV source code, one can find that the function called has this code (modules/core/src/convert.cpp, line 341):
void cv::merge(InputArrayOfArrays _mv, OutputArray _dst)
{
CV_OCL_RUN(_mv.isUMatVector() && _dst.isUMat(),
ocl_merge(_mv, _dst))
std::vector<Mat> mv;
_mv.getMatVector(mv);
merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst);
}
the last line here calls the function 'void cv::merge(const Mat mv, size_t n, OutputArray _dst)*', which has the infamous CV_Assert( mv && n > 0 ); instruction in its first line, causing the crash at runtime.
This error tells us that the vector of Mat is either a null pointer/reference or empty, which it clearly isn't in your code. I strongly suspect that the error is in the getMatVector function call, not copying the contents of _mv into mv. This leaves an empty array that is passed to the merge function, causing the error raised by CV_Assert.
In my case, the fix was to use directly the prototype of the function defined at line 200 in convert.cpp. For you, that would mean (copying only the last few lines of your code):
stacked_images.clear();
stacked_images.push_back(medianb_eq); /*B*/
stacked_images.push_back(mediang_eq); /*G*/
stacked_images.push_back(medianr_eq); /*R*/
merge(&stacked_images[0], stacked_images.size(), objrgb);
This solution worked in my case, and my code is now happily running in debug and release mode !
PS: I know it has been a while, but thought I would post the answer anyway in case somebody running into the same problem would arrive on this SO question.
PS2: Here is a full example code:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main( int argc, char** argv )
{
namedWindow( "Display window", WINDOW_AUTOSIZE );
Mat result;
Mat R = imread("Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
Mat G = imread("Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
Mat B = imread("Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
// Changing channel values for final result that should look largely blue
R = 0.1*R;
G = 0.1*G;
B = 1.5*B;
std::vector<cv::Mat> array_to_merge ;
array_to_merge.push_back(B);
array_to_merge.push_back(G);
array_to_merge.push_back(R);
// This line triggers a runtime error in Release mode
//cv::merge(array_to_merge,result);
// This line works both in Release and Debug mode
cv::merge(&array_to_merge[0], array_to_merge.size(), result);
cv::imshow( "Display window", result );
cv::waitKey(0);
}
Although you could write it in a lot fewer lines , this code is valid.

OpenCV resize is not a member of cv (OpenCV Basics)

I successfully wrote a tool that converts an image's colors space from linear to sRGB, so opencv is working. Then i wanted to rescale the image with the cv::resize function to generate Thumbnails. However it didn't work, here is the reproduced code-snippet.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
int main( int argc, char** argv )
{
// Load images in the C++ format
cv::Mat img = cv::imread("something.jpg");
cv::Mat src = cv::imread("src.jpg");
// Resize src so that is has the same size as img
**cv::resize**(src, src, img.size());
return 0;
}
I am using OpenCV 2.4.8. What am i doing wrong?
you're lacking a header file:
#include "opencv2/imgproc/imgproc.hpp"
(ofc, you have to link opencv_imgproc, too)
#include "opencv2/opencv.hpp"
would have avoided the 1st error, but you still have to care for the correct libs

Merging two images showing brightness

I am trying to blend two image or you can say put one image on other image , when i apply blending overlay on the image or simple merge two image it show me brightness in it.
here are my two images (first vignette is empty from inside , its not containing brightness in the centre )
and the other is
The code which i did is
int main( int argc, char** argv )
{
Mat img=imread("E:\\vig.png",-1);
Mat ch[4];
split(img,ch);
Mat im2 = ch[3]; // here's the vignette
im2 = 255 - im2; // eventually cure the inversion
Mat img2 = imread("E:\\ew.jpg");
Mat out2;
blending_overlay3(img2 , im2 , out2);
imshow("image",out2);
imwrite("E:\\image.jpg",out2);
waitKey();}
It show me the result like
but i require result like
EDIT
The first image is hollow/empty from center (the vignette one) , but when i read the image (vignette one) with my program then it become solid(bright) from the center , the history behind its implementation is here
There is the only problem and its with first (vignette) image reading , if it read as it is , like hollow/empty from the center , so that the other image with which we merge/blend/weight whatever apply it didn't effect the center part of the image , not even show brightness etc , that's what i want to do
it's me again :) It seems you are writing new photoshop.
The result I've got:
The code:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <functional>
#include <algorithm>
#include <numeric>
#include <cstddef>
#include "opencv2/opencv.hpp"
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
namedWindow("Image");
Mat Img1=imread("Img1.png",-1);
Mat Img2=imread("Img2.png");
cv::resize(Img1,Img1,Img2.size());
Img1.convertTo(Img1,CV_32FC4,1.0/255.0);
Img2.convertTo(Img2,CV_32FC3,1.0/255.0);
vector<Mat> ch;
split(Img1,ch);
Mat mask = ch[3].clone(); // here's the vignette
ch.resize(3);
Mat I1,I2,result;
cv::multiply(mask,ch[0],ch[0]);
cv::multiply(mask,ch[1],ch[1]);
cv::multiply(mask,ch[2],ch[2]);
merge(ch,I1);
vector<Mat> ch2(3);
split(Img2,ch2);
cv::multiply(1.0-mask,ch2[0],ch2[0]);
cv::multiply(1.0-mask,ch2[1],ch2[1]);
cv::multiply(1.0-mask,ch2[2],ch2[2]);
merge(ch2,I2);
result=I1+I2;
imshow("Image",result);
waitKey(0);
}

Assertion failed <dst.data != src.data > in unknown function ../../ocv/opencv/modules/imgproc/src/imgwarp.cpp

Hey please can someone help me to found the solution of this error :
Assertion failed in unknown function ../../ocv/opencv/modules/imgproc/src/imgwarp.cpp
i try to compile the code that exist in this link : http://ipwithopencv.googlecode.com/svn/trunk/ThinPlateSpline/ThinPlateSpline/
im using 2 classes and the main:
here is my main code :
#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include "CThinPlateSpline.h"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
// load a nice picture
cv::Mat img = cv::imread("lena.jpg");
// generate some generic points
// usually you would use a interest point detector such as SURF or SIFT
std::vector<cv::Point> iP, iiP;
// push some points into the vector for the source image
iP.push_back(cv::Point(50,50));
iP.push_back(cv::Point(400,50));
iP.push_back(cv::Point(50,400));
iP.push_back(cv::Point(400,400));
iP.push_back(cv::Point(256,256));
iP.push_back(cv::Point(150,256));
// push some point into the vector for the dst image
iiP.push_back(cv::Point(70,70));
iiP.push_back(cv::Point(430,60));
iiP.push_back(cv::Point(60,410));
iiP.push_back(cv::Point(430,420));
iiP.push_back(cv::Point(220,280));
iiP.push_back(cv::Point(180,240));
// create thin plate spline object and put the vectors into the constructor
CThinPlateSpline tps(iP,iiP);
// warp the image to dst
Mat dst;
tps.warpImage(img,dst,0.01,INTER_CUBIC,BACK_WARP);
// show images
cv::imshow("original",img);
cv::imshow("distorted",dst);
//cv::waitKey(0);
//Sleep(5);
cv::waitKey(5000);
return 0;
}
here is the is the imagewarp method :
void CThinPlateSpline::warpImage(const Mat& src, Mat& dst, float lambda, const int interpolation,const TPS_INTERPOLATION tpsInter)
{
Size size = src.size();
dst = Mat(size,src.type());
// only compute the coefficients new if they weren't already computed
// or there had been changes to the points
if(tpsInter == BACK_WARP && !FLAG_COEFFS_BACK_WARP_SET)
{
computeSplineCoeffs(pSrc,pDst,lambda,tpsInter);
}
else if(tpsInter == FORWARD_WARP && !FLAG_COEFFS_FORWARD_WARP_SET)
{
computeSplineCoeffs(pSrc,pDst,lambda,tpsInter);
}
computeMaps(size,mapx,mapy);
remap(src,dst,mapx,mapy,interpolation);
}
there is to other classes that exist in the link also CthinPlateSpline.cpp and CthinPlateSpline.h ...please i really need help and sorry for my bad english
"Assertion failed" in OpenCV usually happens when your input Mat has incorrect size, e.g. zero (empty Mat) or less than the requirement of the function.
Would you mind to check img after cv::Mat img = cv::imread("lena.jpg");
by img.empty() or display img by imshow?
I can run these on my mac with OpenCV 2.4.7
The result image is a twisted lena
I just change two places as following
First of all, I change the included file in main.cpp to become
#include <opencv2/opencv.hpp>
#include "CThinPlateSpline.h"
#include <iostream>
#include <vector>
And included file in CThinPlateSpline.cpp to become
#include <vector>
#include <opencv2/opencv.hpp>
#include "CThinPlateSpline.h"
I use only 3 files main.cpp, CThinPlateSpline.cpp, and CThinPlateSpline.h
libraries linked are
-lopencv_imgproc -lopencv_core -lopencv_highgui
Verify if the image was loaded correctly. In my case (OpenCV for Python) my image was not loaded at all.
Try to verify what image exactly are you passing to the function.