2009年8月10日星期一

利用OpenCV进行图像连接

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

/* プロトタイプ宣言 */
IplImage *combine_image (int num, IplImage ** tmp);

/* メイン関数 */
int
main (int argc, char **argv)
{
  int i, img_num;
  IplImage **img;
  IplImage *combined_img;

  // (1)コマンド引数で指定された画像を全て読み込む
  if (argc < 2) {
    return 1;
  }
  else {
    img_num = argc - 1;
    img = (IplImage **) cvAlloc (sizeof (IplImage *) * img_num);
    for (i = 0; i < img_num; i++) {
      img[i] = cvLoadImage (argv[i + 1], CV_LOAD_IMAGE_COLOR);
      if (img[i] == 0)
        return -1;
    }
  }

  // (2)画像を連結する
  combined_img = combine_image (img_num, img);

  cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE);
  cvShowImage ("Image", combined_img);
  cvWaitKey (0);

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

  return 0;
}

/* 画像を連結する関数 */
IplImage *
combine_image (int num, IplImage ** tmp)
{
  int i;
  int width = 0, height = 0;
  IplImage *cimg;
  CvRect roi = cvRect (0, 0, 0, 0);

  // (3)与えられた各画像から,連結後の幅と高さを求める
  for (i = 0; i < num; i++) {
    width += tmp[i]->width;
    height = height < tmp[i]->height ? tmp[i]->height : height;
  }
  cimg = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3);
  cvZero (cimg);

  // (4)ROIを利用して各画像をコピーする
  for (i = 0; i < num; i++) {
    roi.width = tmp[i]->width;
    roi.height = tmp[i]->height;
    cvSetImageROI (cimg, roi);
    cvCopy (tmp[i], cimg);
    roi.x += roi.width;
  }
  cvResetImageROI (cimg);

  return cimg;
}

// (1)コマンド引数で指定された画像を全て読み込む
コマンド引数で指定された画像を全て,カラー画像として読み込む.そのなかに1つでも読み込めない画像がある場合には終了する.

// (2)画像を連結する
あらかめ定義した関数combined_img()を呼び出して,画像を横方向に連結する.この例では単純に画像の上辺を揃えて横方向に連結を行うだけであるが,画像を折り返して連結したり,さらにいわゆる「矩形パッキング問題」をの解を求めることで無駄な領域が小さくなるように連結することもできる.また,このサンプルでは連結する関数combined_image()に画像のポインタの配列を渡しているが,可変引数を利用(stdarg.h)して,combine_image()を次のように定義する方法もある.

IplImage*
combine_image(int num, ...)
{
  va_list list;
  int i;
  int width = 0, height = 0;
  IplImage *tmp[num];
  IplImage *cimg;
  CvRect roi = cvRect(0, 0, 0, 0);
        
  va_start(list, num);
  for(i=0; iwidth;
    height = height < tmp[i]->height ? tmp[i]->height : height;
  }
  va_end(list);
  cimg = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
  cvZero(cimg);

  for(i=0; iwidth;
    roi.height = tmp[i]->height;
    cvSetImageROI(cimg, roi);
    cvCopy(tmp[i], cimg);
    roi.x += roi.width;
  }
  cvResetImageROI(cimg);
  
  return cimg;
}

没有评论:

发表评论

欢迎访问、交流!对本博客有何建议,请
来信告知!
本博内容来源于网络,如有不当或侵犯权益,请来信告知,将及时撤除!
如引用博客内容、论文,请注明原作者!

Google一下本博客

  • 《Getting Things Done》读书笔记 - 本文来自 inertial 原创投稿。 我第一次听说《Getting Things Done》这本书的时候误以为它和世面上的那些成功学书籍没什么区别,后来在不少书中看到了这个名字,也看见了很多人的推荐,由此产生了很大的兴趣。上个月正好有不少空闲,就抽时间把这本书读完了。 本来打算读英文原版,但是原版的生...
    5 年前
  • [原]Linux下编译使用boost库 - Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一。 Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容。在C++社区中影响甚大,是不折不扣的“准”标准库。Boost由于其对跨平台的强调,对标准C++的强调,与...
    6 年前
  • [原]猎头、培训与咨询的价值(2)【补1】——北漂18年(93) - 【上期用手机写的,同时用语音输入转化成文字,错字较多,经好友霍师傅提醒本期重写,并增加一部分新内容】 简单谈下我对猎头、培训与咨询的看法。三样都干过,算是有些浅见。 猎头 简单的说就是人才中介。虽然在公司看来是可以直接解决现有企业问题的一个直接方法,但很多时候都不太管用。 猎头费一般是人才的一个月月...
    7 年前
  • OpenCV統計應用-Mahalanobis距離 - Mahalanobis距離是一個可以準確找出資料分布上面極端值(Outliers)的統計方法,使用線性迴歸的概念,也就是說他使用的是共變數矩陣以及該資料分布的平均數來找尋極端值的產生,而可以讓一群資料系統具有穩健性(Robust),去除不必要的雜訊訊息,這邊拿前面共變數矩陣的資料為例,並且新增了兩個點座標向量來做...
    15 年前
  • 努力推进模式识别实际产品的开发与应用 - Salu 无论是手写体识别、文档处理、人脸识别、基于内容的图片搜索、嵌入人工智能的搜索技术、虚拟网络社区、还是其它相关新科技下的信息整合领域,现在都在努力实用化。 前两年、即使现在还有很多人在抱怨说人脸的方法都不能用,但是就今年出现的和正在做的有关人脸识别实际应用的各种形式的产品可以说如雨后春笋。这是一个趋...
    16 年前