OpenCV: загрузка нескольких изображений - PullRequest
0 голосов
/ 16 июля 2010

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

Что я хочу сделать сейчас, это просто загрузить серию изображений (передаваемых в качестве аргументов командной строки) в виде Mats.Это часть большой задачи.Первый пример кода ниже - это метод загрузки изображения старого кода.Он загружает 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 ]

2 голосов
/ 18 июля 2010

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

например

#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 голосов
/ 22 июля 2010

Мне потребовалось некоторое время, чтобы вернуться к этому, но то, что я в итоге сделал, заключается в следующем, что, вероятно, функционально совпадает с предложением Гутика.Это хорошо сработало для меня.Обратите внимание, что для функций, которые принимают Mat& (то есть один cv::Mat), вы можете просто де-рефилировать массив Mats и передать его, что является нотацией, с которой мне удобнее после выполнения большой работы по обработке изображенийв 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...