Unexpected result when Comparing sample image with database of images - Opencv c++ - c++

I am working on Image matching program, it captures image from IR camera stores it in one directory. A database of images exist in a different directory. I get an unexpected result while executing. I somehow realize that it's because I'm messing with different directories and something basic. Any help in getting around the mistake? Here's a snippet of the code.
VideoCapture cap(0);
Mat frame;
Mat src, dst, tmp,img_3,img_4;
filename3 = (char *)malloc(sizeof(char));
printf("\n-------------------------------------------------\n");
printf("\nOne to Many Image matching with SURF Algorithm.\n");
printf("\n-------------------------------------------------\n");
//Get the Vein image from Webcam that needs to be compared with the database.
// The below function gets frame and saves it in /home/srikbaba/opencv/veins
veincnt = captureVein(veincnt, cap);
if(veincnt == -1)
cout << "A problem has occured" << endl;
printf("\nPlease enter the filename of saved image with the extension.\n");
scanf("%s",filename3);
//Scan the directory for images.
DIR *dir;
struct dirent *ent;
clock_t tstart1 = clock(); //start clock function, do something!!!!
if ((dir = opendir ("/home/srikbaba/images")) != NULL)
{
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL)
{
if(ent->d_type!= DT_DIR)
{
//Print the images
printf ("%s\n", ent->d_name);
//Store the Filename
img_db = ent->d_name;
//Open each file name as Mat identifier and loop the process
img_3 = imread (filename3, IMREAD_GRAYSCALE);
//Filename3 is saved in /home/srikbaba/opencv/veins --> different directory
// I feel this is the problem
img_4 = imread (img_db, IMREAD_GRAYSCALE);
if( !img_3.data)
{
std::cout<< " --(!) Invalid filename or file not found! " << std::endl;
return -1;
}
Because of this I always get --(!) Invalid filename or file not found message. Is there a way I can compare one image from a directory and another image from a different directory? I hope what I asked is not confusing. Kindly help.
Working on Opencv - C++ on Ubuntu 12.04 LTS

You are getting undefined behavior because you are allocating space for only 1 character for filename3 in the following line:
filename3 = (char *)malloc(sizeof(char));
So in the following line...
scanf("%s",filename3);
Any file name greater than 1 character will invoke undefined behavior.
In my opinion, there is no need of malloc. You can just allocate large enough filename3 of fixed size like this:
char filename3[256];

Related

OpenCV trying to read or write to video file causes VIDEOIO exception "Can't find starting number" (icvExtractPattern)

So for a school project, I am trying to use cv::VideoCapture to open a .avi file to perform some image processing on it. Also, I am trying to record the video from my (Laptop) camera and save it to a file out.avi. Both times I encountered more or less the same exception.
I am using OpenCV 4.1.2 and CLion on Linux Mint.
Trying to use cv::VideoCapture vid(0); works perfectly fine, it shows the output from the Laptop's camera. However, when specifying a path to a video file to open, I get the following error:
VIDIOC_REQBUFS: Inappropriate ioctl for device
[ERROR:0] global /home/aris/dev/opencv/modules/videoio/src/cap.cpp (116) open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.1.2-dev) /home/aris/dev/opencv/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): ../example_depth.avi in function 'icvExtractPattern'
When trying to create a cv::VideoWriter object (to save the camera video ouput to a file) using:
cv::VideoWriter vidWrit("out.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, cv::Size(width, height), true);
I am encountering this error:
[ERROR:0] global /home/aris/dev/opencv/modules/videoio/src/cap.cpp (392) open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.1.2-dev) /home/aris/dev/opencv/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): out.avi in function 'icvExtractPattern'
Which looks kind of similar to the other one.
Here is a minimal example (note that the program still shows the camera output in task == "write"):
#include <opencv2/opencv.hpp>
int main ()
{
std::string task = "write";
if(task == "read") { // Read from .avi file
system("pwd"); // Print current path
cv::VideoCapture vid("../example_depth.avi"); // Throws first exception "Inappropriate ioctl for device"
int key = 0;
cv::Mat frame;
while (key != 27) {
vid >> frame;
if (frame.empty())
break;
cv::imshow("Video", frame);
key = cv::waitKey(25);
}
} else if (task == "write") { // Write Laptop video to file
cv::VideoCapture vid(0); // Video from camera
int width = vid.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH);
int height = vid.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT);
cv::VideoWriter vidWriter("out.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, cv::Size(width, height), true); // Throws second exception
int key = 0;
cv::Mat frame;
while (key != 27) {
vid >> frame;
if (frame.empty())
break;
vidWriter.write(frame);
cv::imshow("Video", frame);
key = cv::waitKey(25);
}
}
return 0;
}
I've been looking for a solution for two days now. Maybe I am missing some library or OpenCV didn't get installed correctly, I don't know about that (yes, I've tried 'recompiling' OpenCV). I used this tutorial to make all the OpenCV files.
Did the file you want to write to (out.avi) already exist?
I got this error with opencv-python==4.1.2.30 and changing the output to a filepath that did not exist solved it for me.
I've seen this issue a couple of times. First check if the path to the video is correct. In your case, "out.avi" should exist. So this is probably is a dependency or conflict issue. My speculation is that this error occurs when a backend video encoder library conflicts with OpenCV. Try reinstalling the libraries. I suggest you follow the instructions from the official documentation, and open an issue if you keep experiencing problems.

OpenCV VideoCapture works inconsistently

I have been trying to get my application using OpenCV to work for a while now and a longstanding error which I cannot seem to fix is this one:
PROBLEM:
OpenCV's VideoCapture is inconsistent in splitting video into frames for different file formats and codecs.
Specifics:
My errors are in one part of the application: splitting videos into frames. There are three current scenarios when I choose a valid directory for VideoCapture and open it. It either:
Opens and works perfectly.
Is able to open the VideoCapture (cap.isOpened() = true) but receives an empty frame or two during the frame split which causes app to throw error.
Does not open at all.
A given video will only do one of those three things. AVI File formats seem to have most of the errors, though.
Fixes tried:
Installing K-Lite Codec Pack Full
Putting OpenCV_FFMPEG.dll and OpenCV_FFMPEG_64.dll in project directory and in PATH
The only explanation I can think of is this is an error with the way I installed OpenCV and FFmpeg.
Any help would be greatly appreciated! Thanks.
By the way, I am running Qt 5.8.0 and OpenCV 3.2.0 and this is my FrameSplit code.
vector<int> mainFrame::frameSplit(string filename, string location)
{
//Extract + Save Frames
string vidDir = filename;
string locationDir = location + "/frames/";
VideoCapture cap(vidDir);
if (!cap.isOpened())
{
qDebug() << "OO";
return {};
}
else
{
Mat firstFrame;
Mat nextFrame;
Mat frame;
int count = 1;
QProgressDialog progress("Extracting files...", "Abort", 0, cap.get(CV_CAP_PROP_FRAME_COUNT));
progress.setWindowModality(Qt::WindowModal);
progress.setAttribute(Qt::WA_DeleteOnClose, true);
progress.setFixedSize(500, 100);
progress.show();
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);
qDebug() << cap.get(CV_CAP_PROP_FRAME_COUNT);
bool failure = false;
for (count = 1; count < cap.get(CV_CAP_PROP_FRAME_COUNT); count++)
{
cap >> frame;
if(frame.empty()) {
QMessageBox messageBox;
messageBox.critical(this, "Error", "There was an error in analyzing the video. Please try and install the appropriate codecs and try again.");
messageBox.setFixedSize(600,400);
vector<int> empty;
return empty;
}
string filePath = locationDir + to_string(count) + ".jpg";
imwrite(filePath,frame,compression_params);
progress.setValue(count);
}
progress.setValue(count);
progress.close();
vector<int> props;
props.push_back(cap.get(CV_CAP_PROP_FRAME_COUNT));
props.push_back(round(cap.get(CV_CAP_PROP_FPS)));
props.push_back(cap.get(CV_CAP_PROP_FRAME_WIDTH));
props.push_back(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
qDebug() << props[0];
return props;
}
}

imread() won't read string variable in c++

char file[1024];
FILE *f;
f= popen("zenity --file-selection", "r");
std:: string result = fgets(file,1024,f);
Mat img = imread(result, CV_LOAD_IMAGE_COLOR);
if(img.empty())
{
cout<<"Image is empty";
return -1;
}
resize(img,img,Size(40,56));
.........
.........
The output to the above code is "Image is empty"
The imread() function from opencv is not recognizing the path(string) hence unable to read the image. How to resolve this?
Thanks for help in advance!

warning: Error opening file (/build/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp:578)

I cannot access ipcamera on opencv, I'm using ipcctrl app to view camera preview and it's working fine, but when I try to paste the URL into my code it displays warning: Error opening file (/build/opencv/modules/videoio/src/cap_ffmpeg_impl.hpp:578) what's the problem here ?here is the proof that it is working fine in ipcctrl
cv::Mat imgFrame1;
cv::Mat imgFrame2;
cv::VideoCapture capVideo;
const std::string videoStreamAddress = "http://admin:admin#192.168.8.50:8088/mjpeg.cgi?user=USERNAME&password=PWD&channel=0&.mjpg";
std::vector<Blob> blobs;
cv::Point crossingLine[2];
int carCount = 0;
std::ofstream writer;
writer.open("cars.txt");
writer.close();
capVideo.open(videoStreamAddress);
if (!capVideo.open(videoStreamAddress)) { // if unable to open video file
std::cout << "error reading video file" << std::endl << std::endl; // show error message
_getch(); // it may be necessary to change or remove this line if not using Windows
return(0); // and exit program
}
I already solved this problem, turns out that I have an incorrect URL for the videostream address, the hard part is my camera is not that known and had a little documentations about how to configure it. I used the ispy app to generate a proper URL for my kedacom camera, tested it on VLC and on the app and viola ! it worked.

doesn't save any image.. when saving frames of a video [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Cant save image using OpenCV
I have tried following code,please see this and tell me what did i wrong.but there is not compile error.after i run the program it doesn't save any image.
#include"stdafx.h"
#include<cv.h>
#include<highgui.h>
#include<cxcore.h>
int main(int argc, char* argv[]) {
int c=1;
IplImage* img=0;
char buffer[1000];
CvCapture* cv_cap=cvCaptureFromCAM(-1);
cvNamedWindow("Video",CV_WINDOW_AUTOSIZE);
while(1) {
img=cvQueryFrame(cv_cap);
cvShowImage("Video",img);
sprintf(buffer,"D:/image%u.jpg",c);
cvSaveImage(buffer,img);
c++;
if (cvWaitKey(100)== 27) break;
}
cvDestroyWindow("Video");
return 0;
}
can you tell me how to save a image .above program doesn't save any images.please give me your suggestions.thank you.
IplImage *destination = cvCreateImage(cvSize( img->width, img->height ), IPL_DEPTH_8U,1);
cvCvtColor( img, destination, CV_RGB2GRAY );
cvSaveImage( "C:/Users/SP/Desktop/sample.jpg", destination );
It converts to grey image; use it as desired.
Hope this works.
Probably a permissions problem, only admin can write to the top level folder
Try making a sub-directory and writing to eg sprintf(buffer,"D:/data/image%u.jpg",c);
I'll say this for the 100th time in these OpenCV posts: code safely by checking the return of the calls. cvSaveImage() returns 0 when it fails to save the image:
if (!(cvSaveImage(buffer,img))
{
std::cout << "!!! Failed to save image" << std::endl;
}
If you see the error message being displayed, you should check if the destination directory exists and if your user has the authorization to create files inside it.