ラベル OpenCV の投稿を表示しています。 すべての投稿を表示
ラベル OpenCV の投稿を表示しています。 すべての投稿を表示

2012年4月27日金曜日

OpenCV 画像の90度回転

テキストをパースして、複数の画像を1枚にまとめてみる テスト

パース処理にboostのtokenizerを使用

貼り付ける画像が、貼り付け先の画像からはみ出るとエラーになるよ


テキストファイルの例

2                     <-- 貼り付ける画像数
1024 512              <-- 貼り付け先の画像の幅, 高さ
c:/temp/test1.bmp"    <-- 画像の絶対パス
0 0 0 200 200 0       <-- [画像のインデックス] [X座標] [Y座標] [幅] [高さ] [※回転]
c:/temp/test2.bmp"
1 210 0 32 128 1

main.cpp

#include <fstream>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

// 貼り付ける画像情報
struct ImageInfo {
  std::string   path;   // ファイルの絶対パス
  int       param[6]; // パラメータ
};

// src_imgをdst_imgのrect領域にコピー
void MatCopyPaste(const cv::Rect& rect, cv::Mat& dst_img, cv::Mat& src_img) {
  cv::Mat d = dst_img(rect);    // 貼り付け先のMatを取得
  src_img.copyTo(d);        // 貼り付け画像をコピーする
}

// 1画像の処理
void ImageProc(cv::Mat& dst_img, const ImageInfo& info) {
  // 貼り付ける画像を読み込む
  cv::Mat src_img = cv::imread(info.path, 1);
  assert(!src_img.empty());

  // 貼り付け先の画像のサイズ
  int imgWidth = info.param[3];
  int imgHeight = info.param[4];
  // 貼り付け位置
  int imgX = info.param[1];
  int imgY = info.param[2];

  // 貼り付け画像
  cv::Mat tmp_img(cv::Size(imgWidth, imgHeight), src_img.type());

  if(info.param[5] == 1) {
    // 画像を回転
    int src_w = src_img.size().width;
    int src_h = src_img.size().height;
    
    cv::Mat rot_img(cv::Size(src_h, src_w), src_img.type(), cv::Scalar(0, 0, 0));
    cv::transpose(src_img, rot_img);  // 転置 左回り 反時計回りに90度回転 
    cv::flip(rot_img, rot_img, 1);    // 左右反転 時計回りに90度回転

    cv::resize(rot_img, tmp_img, tmp_img.size(), cv::INTER_CUBIC);
  } else {
    // サイズ変更
    cv::resize(src_img, tmp_img, tmp_img.size(), cv::INTER_CUBIC);
  }

  // 指定した矩形に画像を貼り付ける
  cv::Rect rect(imgX, imgY, imgWidth, imgHeight); 
  MatCopyPaste(rect, dst_img, tmp_img);
}

int main( int argc, char **argv ) {
  int count = 0;
  std::string str;
  // 貼り付ける画像を記述したテキストファイルを読み込む
  std::ifstream ifs( "./data/ImgList.txt" );

  typedef boost::char_separator char_sep;
  typedef boost::tokenizer tokenizer;
  char_sep sep(" ");    // スペース区切り

  int imgNum, imgWidth, imgHeight;
  std::vector  imgDataArray;
  ImageInfo imgData;

  while(std::getline(ifs, str)) {
    std::vector tokenArray;

    // 読み込んだ文字列をトークンに分割して配列に格納
    tokenizer tok(str, sep);
    for (tokenizer::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter) {
      tokenArray.push_back( *tok_iter );
    }

    switch(count) {
    case 0:  // 画像数
      // int にキャスト
      imgNum = boost::lexical_cast(tokenArray[0]);
      break;
    case 1:  // 画像の幅と高さ
      imgWidth = boost::lexical_cast(tokenArray[0]);
      imgHeight = boost::lexical_cast(tokenArray[1]);
      break;
    default: // 画像のパラメータ
      if(0 == count % 2) {
        // ファイルパス
        imgData.path = tokenArray[0];
      } else {
        // パラメータ
        for(int i = 0; i < 6; i++) {
          imgData.param[i] = boost::lexical_cast(tokenArray[i]);
        }
        imgDataArray.push_back(imgData);
      }
      break;
    }
    count++;
  }

  // 貼り付け先の画像
  cv::Mat dstImg(cv::Size(imgWidth, imgHeight), CV_8UC3, cv::Scalar(0, 0, 0));

  // 画像処理
  for(size_t i = 0; i < imgDataArray.size(); i++) {
    ImageProc(dstImg, imgDataArray[i]);
  }

  // 結果を保存
//  cv::imwrite("./data/result.png", dstImg);

  // 結果を表示
  cv::namedWindow("Result", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
  cv::imshow("Result", dstImg);
  cv::waitKey(0);
  return 0;
}

2012年2月7日火曜日

OpenCVでペイント

OpenCVのテスト用

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

cv::Mat g_Canvas; // キャンバス
cv::Mat g_Palette; // 描画色
cv::Size g_CanvasWndSize(640, 480); // キャンバスサイズ
const char* g_CanvasWndName = "window";
const char* g_PalWndName = "palette";
bool g_bLBtnDown = false;
int g_TrackBarValue[3] = { 0 };  // トラックバーの値

// 指定座標にピクセル描画
void DrawPixel(cv::Mat* pMat, int x, int y, int pixelSize)
{
 cv::Scalar color(g_TrackBarValue[2], g_TrackBarValue[1], g_TrackBarValue[0]);
 cv::Point p0(x - pixelSize, y - pixelSize); 
 cv::Point p1(x + pixelSize, y + pixelSize); 
 cv::rectangle(*pMat, p0, p1, color, -1, CV_AA);
}

// マウスイベントの処理
static void onMouse(int event, int x, int y, int flag, void* ptr)
{
 switch(event) {
 case cv::EVENT_MOUSEMOVE:
  if(g_bLBtnDown) {
   // キャンバスにピクセル描画
   DrawPixel(&g_Canvas, x, y, 4);

   // 変更を反映
   cv::imshow(g_CanvasWndName, g_Canvas);
  }
  break;
 case cv::EVENT_LBUTTONDOWN:
  g_bLBtnDown = true;
  break;
 case cv::EVENT_LBUTTONUP:
  g_bLBtnDown = false;
  break;
 }
}

// 指定色で塗りつぶす
void FillColor(cv::Mat* pMat, int r, int g, int b)
{
 *pMat = cv::Scalar(b, g, r);
}

// トラックバーのイベントハンドラ
void onTrackbarRed(int val, void* ptr)
{
 g_TrackBarValue[0] = val;
 FillColor(&g_Palette, g_TrackBarValue[0], g_TrackBarValue[1], g_TrackBarValue[2]);
 cv::imshow(g_PalWndName, g_Palette);
}
void onTrackbarGreen(int val, void* ptr)
{
 g_TrackBarValue[1] = val;
 FillColor(&g_Palette, g_TrackBarValue[0], g_TrackBarValue[1], g_TrackBarValue[2]);
 cv::imshow(g_PalWndName, g_Palette);
}
void onTrackbarBlue(int val, void* ptr)
{
 g_TrackBarValue[2] = val;
 FillColor(&g_Palette, g_TrackBarValue[0], g_TrackBarValue[1], g_TrackBarValue[2]);
 cv::imshow(g_PalWndName, g_Palette);
}

int main( int argc, char **argv )
{
 // Matを作成
 g_Canvas = cv::Mat(g_CanvasWndSize.height, g_CanvasWndSize.width, CV_8UC3);
 g_Palette = cv::Mat(64, 512, CV_8UC3);
 FillColor(&g_Palette, g_TrackBarValue[0], g_TrackBarValue[1], g_TrackBarValue[2]);

 // ウィンドウ作成
 cv::namedWindow(g_CanvasWndName, CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
 cv::namedWindow(g_PalWndName, CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
 
 // マウスのコールバック関数をセット
 cv::setMouseCallback(g_CanvasWndName, onMouse, NULL);
 
 // トラックバーをウィンドウに作成
 cv::createTrackbar("Red", g_PalWndName, &g_TrackBarValue[0], 255, onTrackbarRed, 0);
 cv::createTrackbar("Green", g_PalWndName, &g_TrackBarValue[1], 255, onTrackbarGreen, 0);
 cv::createTrackbar("Blue", g_PalWndName, &g_TrackBarValue[2], 255, onTrackbarBlue, 0);

 // ウィンドウにMatを表示
 cv::imshow(g_CanvasWndName, g_Canvas);
 cv::imshow(g_PalWndName, g_Palette);

 // キー入力待ち
 cv::waitKey(0);
 return 0;
}