2010-07-16 8 views
0

Я обновляю старый код OpenCV, который был написан (я думаю) способом OpenCV 1.1 (т. Е. С использованием IplImages).OpenCV: Загрузите несколько изображений

Что я хочу сделать прямо сейчас, это просто загрузить серию изображений (переданных в качестве аргументов командной строки) в качестве матов. Это часть более крупной задачи. Первый пример кода ниже - метод загрузки образа старого кода. Он загружает 5 изображений из командной строки и отображает их последовательно, приостанавливая нажатие клавиши после каждого, а затем завершает работу.

Второй пример кода - это моя обновленная версия с использованием Mat. Пока это работает, но лучший способ это сделать? Я использовал массив Матов. Должен ли я использовать массив указателей на Матс? И есть ли способ сделать это так, чтобы количество изображений определялось во время выполнения от argc и не нужно заранее устанавливать IMAGE_NUM.

В принципе, я хотел бы иметь возможность передавать любое количество (по причине) изображений в виде аргументов командной строки и загружать их в какой-либо удобный массив или другое подобное хранилище для последующей ссылки.

Спасибо.

Старый код:

#include <iostream> 
#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
using namespace std; 
using namespace cv; 

// the number of input images 
#define IMAGE_NUM 5 

int main(int argc, char **argv) 
{ 
    uchar **imgdata; 
    IplImage **img; 
    int index = 0; 
    char *img_file[IMAGE_NUM]; 

    cout << "Loading files" << endl; 
    while(++index < argc) 
     if (index <= IMAGE_NUM) 
      img_file[index-1] = argv[index]; 

    // malloc memory for images 
    img = (IplImage **)malloc(IMAGE_NUM * sizeof(IplImage *)); // Allocates memory to store just an IplImage pointer for each image loaded 
    imgdata = (uchar **)malloc(IMAGE_NUM * sizeof(uchar *)); 

    // load images. Note: cvLoadImage actually allocates the memory for the images 
    for (index = 0; index < IMAGE_NUM; index++) { 
     img[index] = cvLoadImage(img_file[index], 1); 
     if (!img[index]->imageData){ 
      cout << "Image data not loaded properly" << endl; 
      return -1; 
     } 
     imgdata[index] = (uchar *)img[index]->imageData; 
    } 

    for (index = 0; index < IMAGE_NUM; index++){ 
     imshow("myWin", img[index]); 
     waitKey(0); 
    } 

    cvDestroyWindow("myWin"); 
    cvReleaseImage(img); 

    return 0; 
} 

Новый код:

#include <iostream> 
#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
#include <time.h> 
using namespace std; 
using namespace cv; 

// the number of input images 
#define IMAGE_NUM 5 

int main(int argc, char **argv) 
{ 
    Mat img[IMAGE_NUM]; 
    int index = 0; 

    for (index = 0; index < IMAGE_NUM; index++) { 
     img[index] = imread(argv[index+1]); 
     if (!img[index].data){ 
      cout << "Image data not loaded properly" << endl; 
      cin.get(); 
      return -1; 
     } 
    } 

    for (index = 0; index < IMAGE_NUM; index++) { 
     imshow("myWin", img[index]); 
     waitKey(0); 
    } 
    cvDestroyWindow("myWin"); 
    return 0; 
} 

ответ

2

вы можете использовать вектор вместо массива:

, например

#include <iostream> 
#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
#include <time.h> 
#include <vector> 
using namespace std; 
using namespace cv; 

int main(int argc, char **argv) 
{ 
    vector<Mat> img; 
    //Mat img[IMAGE_NUM]; 
    int index = 0; 

    for (index = 0; index < IMAGE_NUM; index++) { 

     //img[index] = imread(argv[index+1]); 
     img.push_back(imread(argy[index+1])); 

     if (!img[index].data){ 
      cout << "Image data not loaded properly" << endl; 
      cin.get(); 
      return -1; 
     } 
    } 

    vector<Mat>::iterator it; 

    for (it = img.begin(); it != img.end() ; it++) { 
     imshow("myWin", (*it)); 
     waitKey(0); 
    } 
    cvDestroyWindow("myWin"); 
    return 0; 
} 
0

Он взял меня некоторое время, чтобы вернуться к это, но то, что я закончил, заключается в следующем, что, вероятно, функционально совпадает с предложением Gootik. Это хорошо сработало для меня. Обратите внимание, что для функций, которые принимают Mat& (т. Е. Один cv::Mat), вы можете просто отредактировать массив матов и передать это, что является обозначением, с которым мне удобнее после много работы по обработке изображений в Matlab.

#include <iostream> 
#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
using namespace std; 
using namespace cv; 

int main(int argc, char **argv) 
{ 
    if (argc==1){ 
     cout << "No images to load!" << endl; 
     cin.get(); 
     return 0; 
    } 

    int index = 0; 
    int image_num = argc-1; 

    Mat *img = new Mat[image_num]; // allocates table on heap instead of stack 

    // Load the images from command line: 
    for (index = 0; index < image_num; index++) { 
     img[index] = imread(argv[index+1]); 
     if (!img[index].data){ 
      cout << "Image data not loaded properly" << endl; 
      cin.get(); 
      return -1; 
     } 
    } 

    for (index = 0; index < image_num; index++) { 
     imshow("myWin", img[index]); 
     waitKey(0); 
    } 
    cvDestroyWindow("myWin"); 

    delete [] img; // notice the [] when deleting an array. 
    return 0; 
} 
+0

Быстрое обновление: в то время, когда Гутик ответил, я не был знаком с std :: vector библиотеки шаблонов Standad Template Library и не видел значения в его предположении. Теперь, когда я больше знаком с векторами, мне больше нравится его предложение, хотя моя работа отлично подходит для моих целей. – SSilk

Смежные вопросы