1

I want to load a large number of images in my program, to later stitch them together. I am using commandline to mention image address. It works if I know in advance the number of images I will have in input but it doesn't works for variable number of input images:

if (argc < 3)
{
    cerr<<"Usage:" << argv[0] << "SOURCE DESTINATION" << endl;
    return 1;
}

for (int i = 0;i  <argc;i++)
{
    Mat img[i] = imread(argv[i+1], 0);
    imshow("image", img[i]);
}

Is there any other method to get inputs in this case. I need to work on 20 to 25 images. Can I use some file, storing address and read that. I think it is possible, but how does it work?

Edit:

After some modifications, my program now look like this:

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/calib3d/calib3d.hpp"
#include <math.h>
#include <cmath>

#define PI 3.14159
#define max_img 25

using namespace cv;
using namespace std;

//main function
int main(int argc, char** argv)
{const int MAX_NUM_OF_IMG = 1024;
 cv::Mat img[MAX_NUM_OF_IMG];
for(int i=1;i<argc;i++)
  {
std::cout << i << ": " << argv[i] << std::endl;
  img[i-1] = imread(argv[i],0); 
std::cout << "Finished reading images1" << std::endl; 
  imshow("image",img[i]);
//start stitching operations

  }std::cout << "Finished reading images2" << std::endl;
cv::waitKey();
return 0;
}

I gave the following in the commandline:

./img_many camera3/imageb-032.jpgcamera3/imageb-033.jpgcamera3/imageb-034.jpgcamera3/imageb-035.jpgcamera3/imageb-036.jpgcamera3/imageb-037.jpgcamera3/imageb-038.jpgcamera3/imageb-039.jpg

The output I get is

1: camera3/imageb-032.jpgcamera3/imageb-033.jpgcamera3/imageb-034.jpgcamera3/imageb-035.jpgcamera3/imageb-036.jpgcamera3/imageb-037.jpgcamera3/imageb-038.jpgcamera3/imageb-039.jpg
Finished reading images1

OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /build/buildd/opencv-2.3.1/modules/core/src/array.cpp, line 2482
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/buildd/opencv-2.3.1/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat

Aborted (core dumped)

Is it possible to read multiple images from commandline giving them as arguments? Why is it crashing?

Antonio
  • 19,451
  • 13
  • 99
  • 197
Mojo Jojo
  • 369
  • 3
  • 11
  • 31
  • did you try imshow("image",imread(argv[i+1],0)); ? – Alexis Jul 03 '13 at 06:29
  • You might find this helpfully if your stitching images together. Not complete but a start. http://stackoverflow.com/questions/13893464/in-opencv-how-do-i-copy-and-scale-a-greyscale-image-into-another-colour-image – Emile Jul 04 '13 at 23:23

2 Answers2

2

I don't think this compiles. You have to allocate out of the loop an array of cv::Mat

 const int MAX_NUM_OF_IMG = 1024;
 cv::Mat img[MAX_NUM_OF_IMG]; //You could also allocate this dynamically based on the number of arguments/the value of argc

Then, in the loop, you are breaking the boundaries, you have to change it like this:

for(int i=1;i<argc;i++) //You should also check you have not more than MAX_NUM_OF_IMG
  {
  img[i-1] = imread(argv[i],0);  ///What is zero by the way
  imshow("image",img[i]);
  //Probably here you want some short sleep, or a "press a key" event
  }

The number of images you get is argc-1

Then, if you want to have the name of your files stored in some txt file, you can use something like std::ifstream to parse it, as it was std::cin. There are thousands of examples, like this How To Parse String File Txt Into Array With C++

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197
  • 1
    Zero specifies if the image will be read as grayscale or not, if I'm not mistaken – Boyko Perfanov Jul 03 '13 at 06:36
  • 1
    Thanks Antonio!! And yeah Boyko as you said, zero is for loading it in grayscale . – Mojo Jojo Jul 03 '13 at 10:47
  • Anotonio, I tried that , getting this error at run time: OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /build/buildd/opencv-2.3.1/modules/core/src/array.cpp, line 2482 terminate called after throwing an instance of 'cv::Exception' what(): /build/buildd/opencv-2.3.1/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat Aborted (core dumped) – Mojo Jojo Jul 04 '13 at 03:42
  • @Aditi Add a `std::cout << i << ": " << argv[i] << std::endl` in your cycle before imread and let me know the output up to the moment it crashes. In any case, check if the filename with its path is correct. Be sure the filenames do not contain spaces. – Antonio Jul 04 '13 at 06:22
  • In the command line, I gave : ./img_many camera3/imageb-006.jpgcamera3/imageb-007.jpgcamera3/imageb-008.jpgcamera3/imageb-009.jpgcamera3/imageb-010.jpg I get the output upto first imread , which is as follows- 1: camera3/imageb-006.jpgcamera3/imageb-007.jpgcamera3/imageb-008.jpgcamera3/imageb-009.jpgcamera3/imageb-010.jpg It crashes when reaches first imread. – Mojo Jojo Jul 04 '13 at 09:06
  • @Aditi Actually, it crashes after having read already all of your images. Try to put a `std::cout << "Finished reading images" << std::endl;` after the loop. If that message is not printed, please let me now what is the exact line where you have `for`. If that message is printed then this question is answered, and if you have still problems, I suggest that you try to debug the rest of your code and, if necessary, post a new question on stackoverflow. This question should be considered answered. – Antonio Jul 04 '13 at 09:37
  • That message doesn't print. i edited the question just now so as to display the entire code. The output I get is:1: camera3/imageb-032.jpgcamera3/imageb-033.jpg Finished reading images1 OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /build/buildd/opencv-2.3.1/modules/core/src/array.cpp, line 2482 terminate called after throwing an instance of 'cv::Exception' what(): /build/buildd/opencv-2.3.1/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat Aborted (core dumped) – Mojo Jojo Jul 04 '13 at 10:24
  • @Aditi You need to separate with spaces your input filenames, in the command line – Antonio Jul 04 '13 at 11:24
  • @Aditi When I said "Be sure the filenames do not contain spaces" I meant that a file is not called for example "image 001.jpg". – Antonio Jul 04 '13 at 11:39
1

If you have imshow in your load loop you'll basically get a load of flickering. Just load your iamges into your array first.

for(int i=1;i<argc;i++)
{
    std::cout << i << ": " << argv[i] << std::endl;
    img[i-1] = imread(argv[i],0); 
    std::cout << "Finished reading images1" << std::endl;         
}

Afterward try displaying your an image.

imshow("image",img[0]);

You might try adding a key press to loop through displaying your images. I think there is an openCV tutorial that shows this already.

I'm sure i've seen this error a couple of times, each time for a different reason. Images are just arrays, so there is something wrong with one of your images. It could be a bad jpg.

By not displaying each image in your loop, you will hopefully see if there is one image causing the issue.

Also make sure that the 'i' in your loop doesn't get to 25, i.e. an out of bounds exception. You could also putting try/catch statements in to help identify when the error occurs.

Hope that helps you narrow the issue down.

Emile
  • 11,451
  • 5
  • 50
  • 63