画像の横方向への単純連結

29 1月 2010 Under: opencv2.x-samples

C

#include <cv.h>
#include <highgui.h>

int
main (int argc, char **argv)
{
  int i, img_num;
  const char defaultfile[2][32] = {"../image/moon.png", "../image/sunset.png"};
  int total_width=0, max_height=0;
  IplImage **src_img;
  IplImage *combined_img;
  CvRect roi = cvRect(0, 0, 0, 0);

  // (1)load all images specified on the command line
  img_num = argc > 1 ? argc-1 : 2;
  src_img = (IplImage**)cvAlloc(sizeof(IplImage*)*img_num);
  for(i=0; i<img_num; i++) {
    src_img[i] = cvLoadImage (argc-1?argv[i+1]:defaultfile[i], CV_LOAD_IMAGE_COLOR);
    if(src_img[i] == 0)
      return -1;
    total_width += src_img[i]->width;
    max_height = max_height < src_img[i]->height ? src_img[i]->height : max_height;
  }

  // (2)append images one after another
  combined_img = cvCreateImage(cvSize(total_width, max_height), IPL_DEPTH_8U, 3);
  cvZero(combined_img);
  for(i=0; i<img_num; i++) {
    roi.width = src_img[i]->width;
    roi.height = src_img[i]->height;
    cvSetImageROI(combined_img, roi);
    cvCopy(src_img[i], combined_img, NULL);
    roi.x += roi.width;
  }
  cvResetImageROI(combined_img);

  // (3)show the combined image, and quit when any key pressed
  cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE);
  cvShowImage ("Image", combined_img);
  cvWaitKey (0);

  cvDestroyWindow("Image");
  cvReleaseImage(&combined_img);
  for(i=0; i<img_num; i++) {
    cvReleaseImage(&src_img[i]);
  }
  cvFree(&src_img);

  return 0;
}

// (1)コマンドライン引数で指定された画像を全て読み込みます.

コマンドライン引数で指定された画像ファイルを読み込み,IplImage の配列に格納します.また同時に,画像の幅の合計値,高さの最大値を求めます.

// (2)画像を横方向に,単純に連結します.

ROI を利用したコピー(cvCopy)を用いて画像を横方向に連結します.連結の際は,最大の画像高さが利用されるので,高さの小さい画像の下方向には隙間ができます.また,結果画像の幅は,全ての画像の合計値となります.

// (3)連結後の画像を表示し,何かキーが押されると終了します.

結合された画像を表示し,何かキーが押された場合プログラムを終了します.

C++

#include <cv.h>
#include <highgui.h>

using namespace cv;

int
main (int argc, char **argv)
{
  int img_num = argc > 1 ? argc-1 : 2;
  const char defaultfile[2][32] = {"../image/moon.png", "../image/sunset.png"};
  int total_width=0, max_height=0;  

  // (1)load all images specified on the command line
  vector<Mat> src_img;
  for(int i=0; i<img_num; i++) {
    src_img.push_back(imread(argc-1?argv[i+1]:defaultfile[i]));
    Mat last = src_img.back();
    if(!last.data)
      return -1;
    total_width += last.cols;
    max_height = max_height < last.rows ? last.rows : max_height;
  }

  // (2)append images laterally one after another
  Mat combined_img(Size(total_width, max_height), CV_8UC3);
  vector<Mat>::iterator it = src_img.begin(), it_end = src_img.end();
  Rect roi_rect;
  for(; it!=it_end; ++it) {
    roi_rect.width = it->cols;
    roi_rect.height = it->rows;
    Mat roi(combined_img, roi_rect);
    it->copyTo(roi);
    roi_rect.x += it->cols;
  }

  // (3)show the combined image, and quit when any key pressed
  namedWindow("Combined Image", CV_WINDOW_AUTOSIZE);
  imshow("Combined Image", combined_img);
  waitKey(0);

  return 0;
}

// (1)コマンドライン引数で指定された画像を全て読み込みます.

コマンドライン引数で指定された画像ファイルを読み込み,vector に追加します.また同時に,画像の幅の合計値,高さの最大値を求めます.

// (2)画像を横方向に,単純に連結します.

ROI を利用したコピー(Mat.copyTo)を用いて,画像を横方向に連結します.連結の際は,最大の画像高さが利用されるので,高さの小さい画像の下方向には隙間ができます.また,結果画像の幅は,全ての画像の合計値となります.

// (3)連結後の画像を表示し,何かキーが押されると終了します.

結合された画像を表示し,何かキーが押された場合プログラムを終了します.

実行結果例


(左から)入力画像1,入力画像2,結合画像