saving an image to file after processing opencv - c++

I am trying to save an image after I have processed it but unfortunately I am getting an exception. It is running all the lines except the imwrite command (last command on code), and it's throwing this exception:
Unhandled exception at at 0x000007FEFD0D940D in histogram.exe:
Microsoft C++ exception: cv::Exception at memory location 0x00000000001DF720.
How can I fix this error, and what is causing it?
The code I'm using:
int main(int argc, char *argv[])
{
///Loading image to IplImage
//IplImage *img=cvLoadImage(argv[1]);
IplImage *img;
img = cvLoadImage("phidza.JPG",1);
cvShowImage("Ipl",img);
///converting IplImage to cv::Mat
Mat image=cvarrToMat(img);
imshow("Mat",image);
//std::cout<<"size: " << image.size() .height<< " , "
// << image.size().width << std::endl ;
if (image.empty())
{
cout << "Image cannot be loaded..!!" << endl;
return -1;
}
cvtColor(image, image, CV_BGR2GRAY); //change the color image to grayscale image
Mat img_hist_equalized;
equalizeHist(image, img_hist_equalized); //equalize the histogram
//create windows
//namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
namedWindow("output", CV_WINDOW_AUTOSIZE);
//show the image
//imshow("Original Image", image);
imshow("output", img_hist_equalized);
waitKey(0); //wait for key press
imwrite("../output.jpg", img_hist_equalized); // save image
//cvSaveImage("output.jpg", img);
destroyAllWindows(); //destroy all open windows
return 0;
}

This code segment works fine for me, finally the result image got saved.. Binaries might have got corrupted in your case, So better to rebuild the opencv library.

Related

Picture and text on video capture

I would like to put an image on video and i'm wondering if it's possible in opencv without multithreading.
I would like to avoid it because in my project i am operating on RPI 0W(that's whyi don't want multithreading) .
i can't find anything about it on internet. I got some basic code in c++ . I'm new to open cv.
int main(){
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error"<<endl;
return -1;
}
Mat edges;
namedWindow("edges", 1);
Mat img = imread("logo.png");
for (;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("edges", WINDOW_AUTOSIZE );
imshow("edges", img);
imshow("edges", frame);
if (waitKey(30) >= 0) break;
}
}
In OpenCV showing two things in the same window overwrites the previous one which I think is happening in your case.
You can use OpenCV addWeighted() function or bitwise operations.
OpenCV has good documentation on this. You can find it here

How to save an OpenCV 3.2 image to a csv file and then load it to display?

I am trying to perform some operations on an image in which i have to save an image to csv file and later load it to display .I'm working on opencv 3 in which the CvMLData doesn't seem to work as shown in this example here. I guess the functionality has changed in 3.2 version.
CvMLData mlData;
mlData.read_csv("cameraFrame1.csv");
const CvMat* tmp = mlData.get_values();
cv::Mat img(tmp, true);
// set the image type
img.convertTo(img, CV_8UC3);
// set the image size
cv::resize(img, img, cv::Size(320, 256));
tmp->CvMat::~CvMat();
std::cout << "img: " << img << std::endl;
cv::namedWindow("img");
cv::imshow("img", img);
cv::waitKey(0);
Yes, the code you have shown is for OpenCV 2, with the machine learning stuffs all being moved in OpenCV 3. It's probably worth having a read over the Transistion Guide
The code and images below show how you can write a matrix out to a csv file, read it back in, resize it and display all three matrix out to windows.
With this code:
#include <fstream>
void examplethree()
{
cv::Mat mat = imread("mypic.png");
imshow("window", mat);
ofstream outputFile("cameraSamples.csv");
outputFile << format(mat, cv::Formatter::FMT_CSV) << endl;
outputFile.close();
cv::Mat img;
cv::Ptr<cv::ml::TrainData> raw_data = cv::ml::TrainData::loadFromCSV("cameraSamples.csv", 0, -2, 0);
cv::Mat data = raw_data->getSamples();
// optional if you have a color image and not just raw data
data.convertTo(img, CV_8UC3);
img = img.reshape(3); //set number of channels
// set the image type
img.convertTo(img, CV_8UC3);
// set the image size
cv::resize(img, img, cv::Size(320, 256));
//std::cout << "img: " << img << std::endl;
cv::namedWindow("img");
cv::imshow("img", img);
cv::imshow("mat", mat);
cv::waitKey(0);
}

Why can I not see captured image?

I am facing a weird problem.
I am able to load and show image. Also, I am able to capture image but I cannot see image in display. The camera connected fine and capture image fine but cannot see image.
My system is window 10- 64 bit with opencv 3.3.0.
Code is below.
int main()
{
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cerr << "camera didn't connected." << std::endl;
return 0;
}
int nFrame = 0;
cv::Mat image = cv::imread("orgin102.jpg");
cv::imshow("image", image);
cvWaitKey(0);
while (true) {
cv::Mat origin;
cap >> origin;
//flip orign
flip(origin, origin, 1);
nFrame++;
cv::imshow("image", origin);
//if (cv::waitKey(27) >= 0) break;
cvWaitKey(0);
}
return 0;
}
I fixed this problem by changing parameter of cap.
here it is
cv::VideoCapture cap(1);
For some systems, 0 index shows as first camera. and for others index 1 shows first camera.
Hope this helps.
Cheers!

C++ Opencv load CSV file as cv::Mat

I save a cv::Mat as a CSV file which works fine, but when I go to load it and convert it back into a cv::Mat something is being corrupted. When I print out the contents of the cv::Mat they are different from that of the csv file. And when I show the Mat object I get a wide white window.
cv::imwrite("cameraFrame1.jpg", frame);
outFile.open("cameraFrame1.csv");
outFile << cv::format(frame, "CSV") << std::endl;
outFile.close();
...
CvMLData mlData;
mlData.read_csv("cameraFrame1.csv");
const CvMat* tmp = mlData.get_values();
cv::Mat img(tmp, true);
tmp->CvMat::~CvMat();
std::cout << "img: " << img << std::endl;
cv::namedWindow("img");
cv::imshow("img", img);
cv::waitKey(0);
Edit:
I am not at all attached to this method, if there is a better way to save an image to CSV and then read it in as such I will gladly move to that. The point of this is to save the image as raw data, most likely in a database, which could then be opened again in matlab, python, c++ etc.
I needed to set both the image depth and channels, which is the cv::Mat type in c++, as well as the dimensions
cv::imwrite("cameraFrame1.jpg", frame);
outFile.open("cameraFrame1.csv");
outFile << cv::format(frame, "CSV") << std::endl;
outFile.close();
...
CvMLData mlData;
mlData.read_csv("cameraFrame1.csv");
const CvMat* tmp = mlData.get_values();
cv::Mat img(tmp, true);
// set the image type
img.convertTo(img, CV_8UC3);
// set the image size
cv::resize(img, img, cv::Size(320, 256));
tmp->CvMat::~CvMat();
std::cout << "img: " << img << std::endl;
cv::namedWindow("img");
cv::imshow("img", img);
cv::waitKey(0);

OpenCV Having issues with cv::FAST

I'm trying to use the open CV FAST algorithim in order to detect corners from a video feed. The method call and set-up seems pretty straight forward yet I'm running into a few problems. When I try and use this code
while(run)
{
clock_t begin,end;
img = cvQueryFrame(capture);
key = cvWaitKey(10);
cvShowImage("stream",img);
//Cv::FAST variables
int threshold=9;
vector<KeyPoint> keypoints;
if(key=='a'){
//begin = clock();
Mat mat(tempImg);
FAST(mat,keypoints,threshold,true);
//end = clock();
//cout << "\n TIME FOR CALCULATION: " << double(diffClock(begin,end)) << "\n" ;
}
I get this error:
OpenCV Error: Assertion failed (image.data && image.type() == CV_8U) in unknown
function, file ........\ocv\opencv\src\cvaux\cvfast.cpp, line 6039
So I figured its a problem with the depth of the image so I when I add this:
IplImage* tempImg = cvCreateImage(Size(img->width,img->height),8,1);
cvCvtColor(img,tempImg,CV_8U);
I get:
OpenCV Error: Bad number of channels (Incorrect number of channels for this conv
ersion code) in unknown function, file ........\ocv\opencv\src\cv\cvcolor.cpp
, line 2238
I've tried using a Mat instead of a IplImage to capture but I keep getting the same kind of errors.
Any suggestions or help?
Thanks in advance.
The entire file just to make it easier for anyone:
#include "cv.h"
#include "cvaux.hpp"
#include "highgui.h"
#include <time.h>
#include <iostream>
double diffClock(clock_t begin, clock_t end);
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
//Create Mat img for camera capture
IplImage* img;
bool run = true;
CvCapture* capture= 0;
capture = cvCaptureFromCAM(-1);
int key =0;
cvNamedWindow("stream", 1);
while(run)
{
clock_t begin,end;
img = cvQueryFrame(capture);
key = cvWaitKey(10);
cvShowImage("stream",img);
//Cv::FAST variables
int threshold=9;
vector<KeyPoint> keypoints;
if(key=='a'){
//begin = clock();
IplImage* tempImg = cvCreateImage(Size(img->width,img->height),8,1);
cvCvtColor(img,tempImg,CV_8U);
Mat mat(img);
FAST(mat,keypoints,threshold,true);
//end = clock();
//cout << "\n TIME FOR CALCULATION: " << double(diffClock(begin,end)) << "\n" ;
}
else if(key=='x'){
run= false;
}
}
cvDestroyWindow( "stream" );
return 0;
}
Whenever you have a problem using the OpenCV API go check the tests/examples available in the source code: fast.cpp
This practice is extremely useful and educational. Now, if you take a look at that code you will notice that the image gets converted to grayscale before calling cv::FAST() on it:
Mat mat(tempImg);
Mat gray;
cvtColor(mat, gray, CV_BGR2GRAY);
FAST(gray,keypoints,threshold,true);
Seems pretty straight forward, indeed.
You need change this
cvCvtColor(img,tempImg,CV_8U);
To
cvCvtColor(img,tempImg,CV_BGR2GRAY);
You can read this
Good Luck
I started getting the same message with code that had worked previously, and i was certain my Mat was U8 grayscale. It turned out that one of the images i was trying to process was no longer there. So in my case it was a misleading error message.
Take a look at this sample code. The code you are using looks quite outdated opencv, in this sample you will find how feature detectors should be used now.
The sample is generic for several feature detectors (including FAST) so that is like it looks a bit more complicated.
http://code.opencv.org/projects/opencv/repository/entry/branches/2.4/opencv/samples/cpp/matching_to_many_images.cpp
You will also find more samples in the parent directory.
Please follow the following code to have your desired result. For showing an example, I am considering an image only but you can simply use the same idea for video frames
Mat img = imread("IMG.jpg", IMREAD_UNCHANGED);
if( img.empty())
{
cout << "File not available for reading"<<endl;
return -1;
}
Mat grayImage;
if(img.channels() >2){
cvtColor( img, grayImage, CV_BGR2GRAY ); // converting color to gray image
}
else{
grayImage = img;
}
double sigma = 1;
GaussianBlur(grayImage, grayImage, Size(), sigma, sigma); // applying gaussian blur to remove some noise,if present
int thresholdCorner = 40;
vector<KeyPoint> keypointsCorners;
FAST(grayImage,keypointsCorners,thresholdCorner,true); // applying FAST key point detector
if(keypointsCorners.size() > 0){
cout << keypointsCorners.size() << endl;
}
// Drawing a circle around corners
for( int i = 0; i < keypointsCorners.size(); i++ )
{
circle( grayImage, keypointsCorners.at(i).pt, 5, Scalar(0), 2, 8, 0 );
}
cv::namedWindow("Display Image");
cv::imshow("Display Image", grayImage);
cvWaitKey(0);
cvDestroyWindow( "Display Image" );