質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2026閲覧

csvファイルを使って、多くの座標を基に画像の補正を行いたい。

chachamaru0421

総合スコア17

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/01/23 03:24

前提・実現したいこと

現在、マウスで4点の座標を100枚ほどの画像から取得し、csvファイルに出力後、1枚目で取得した座標を基に2枚目以降の画像を1枚目に合うように補正する、ということを行っています。
これは実現できているのですが、4点より多くの座標で補正したいと考えています。以下のコードをどのように改善したら可能なのでしょうか。

該当のソースコード

C++

1#include <opencv2/core/core.hpp> 2#include <opencv2/highgui/highgui.hpp> 3#include <opencv2/opencv.hpp> 4#include <stdio.h> 5#include <stdlib.h> 6#include <fstream> 7#include <iostream> 8#include <sstream> 9#include <vector> 10#include <string> 11#define _CRT_SECURE_NO_WORNINGS 12using namespace cv; 13using namespace std; 14 15vector<string> split(string& input, char delimiter){ 16 istringstream stream(input); 17 string field; 18 vector<string> result; 19 while (getline(stream, field, delimiter)){ 20 result.push_back(field); 21 } 22 return result; 23} 24 25int main(int argc, char **argv){ 26 int Stimulusnumber = 2; 27 IplImage *src_img = 0, *dst_img = 0, *img3 = 0, *img4 = 0; 28 CvMat *map_matrix; 29 float src_pnt[4][2], dst_pnt[4][2]; 30 CvPoint2D32f dst[4], src[4]; 31  //基準となる画像 32 img3 = cvLoadImage("IMG_001.tif", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); 33 //画像の読み込み,出力用画像領域の確保を行なう.補正する画像 34 src_img = cvLoadImage("IMG_002.tif", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); 35 //もし画像がなければ終了 36 if (src_img == NULL) 37 return -1; 38 dst_img = cvCloneImage(src_img); 39 //画像の大きさを揃える 40 IplImage *resrc_img = cvCreateImage(cvSize(480, 640), IPL_DEPTH_8U, 1); 41 cvResize(src_img, resrc_img, CV_INTER_LINEAR); 42 //csvファイルの読み込み.変更前の座標 43 ifstream ifs("IMG_2(1_2).csv"); 44 string line; 45 int j = 0; 46 while (getline(ifs, line)){ 47 vector<string> strvec = split(line, ','); 48 //整数ではなく,浮動小数点型に変換ならstof関数 整数ならstoi関数 49 for (unsigned int i = 0; i<strvec.size(); i++){ 50 if (i % 2 != 0) { 51 //変更前の数字を格納 52 src_pnt[j][0] = stof(strvec.at(i)); 53 } 54 if (i % 2 == 0){ 55 src_pnt[j][1] = stof(strvec.at(i)); 56 } 57 } 58 j = j + 1; 59 } 60 //変更後の座標 61 ifstream ofs("IMG_1(1_2).csv"); 62 j = 0; 63 while (getline(ofs, line)){ 64 vector<string> strvec = split(line, ','); 65 //整数ではなく,浮動小数点型に変換ならstof関数.整数ならstoi関数 66 for (unsigned int i = 0; i<strvec.size(); i++){ 67 //分割した値を代入 68 printf("%5d\n", stoi(strvec.at(i))); 69 if (i % 2 != 0) { 70 //変更後の数字を格納 71 dst_pnt[j][0] = stof(strvec.at(i)); 72 } 73 if (i % 2 == 0) { 74 dst_pnt[j][1] = stof(strvec.at(i)); 75 } 76 } 77 j = j + 1; 78 } 79 int k = 0; 80 //四角形の変換前と変換後の対応する頂点をセット 81 for (k = 0; k< 4; k++) { 82 src[k] = cvPoint2D32f(src_pnt[k][0], src_pnt[k][1]); 83 dst[k] = cvPoint2D32f(dst_pnt[k][0], dst_pnt[k][1]); 84 } 85 //行列の生成 86 map_matrix = cvCreateMat(3, 3, CV_32FC1); 87 //対応している点をそれぞれ配列で変換 88 cvGetPerspectiveTransform(src, dst, map_matrix); 89 //指定された透視投影変換行列により,cvWarpPerspectiveを用いて画像を変換させる 90 cvWarpPerspective(resrc_img, dst_img, map_matrix, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(100)); 91 //点が表示されていない画像を保存する 92 char filename[100]; 93 cv::Mat mat2 = cv::cvarrToMat(dst_img); 94 sprintf_s(filename, "IMG_0%d_dst.tiff", Stimulusnumber); 95 cv::imwrite(filename, mat2); 96 img4 = dst_img; 97 98 return 1; 99}

試したこと

float src_pnt[4][2], dst_pnt[4][2];
CvPoint2D32f dst[4], src[4];
ここの[4]を変えると、実行は出来ましたが、補正がうまくできませんでした。

補足情報

Windows7 32bit
Visual Studio 2010
OpenCV 2.4.10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

cvGetPerspectiveTransform()はちょうど4点を使って透視投影変換行列を生成しますが、5点以上を使って透視投影変換しようとすると矛盾点がでてくるのでその処理をどうするかよく検討し、対策を実装する必要があります。

多数の点を使って統計的に透視投影変換するようなアルゴリズムもあるだろうと思います(私は把握していないです)ので、それらを調査・検討されるのも1つと思います。

投稿2019/01/23 05:38

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chachamaru0421

2019/01/24 03:35

なるほどです…。難しそうですが、探してみます。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問