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

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

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

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

C++

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

Q&A

解決済

1回答

1037閲覧

他の画像を読み込まない

nasu_nasu

総合スコア7

OpenCV

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

C++

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

0グッド

0クリップ

投稿2020/07/27 01:39

指定矩形の画像をもう一つの指定矩形に対して射影変換して埋め込むというプログラムを書いています。
一応完成はしたのですが、imageA.jpgという画像以外で試すと落ちてしまいます。
どうしたら他画像も読み込んでくれるでしょうか?

以下コードです。

c++

1#include <opencv2/opencv.hpp> 2 3using namespace std; 4 5cv::Mat imageA; //入力画像1 6cv::Mat imageP; //枠線記憶用画像 7cv::Mat imageL; //マウス入力用表示画像 8cv::Mat mask; //マスク画像 9cv::Mat pers; //変換後のimage 10cv::Mat results; 11 12cv::Point startp; //四角形の始点 13cv::Point secondp; //四角形の第2点 14cv::Point thirdp; //四角形の第3点 15cv::Point endp; //四角形の終点 16 17cv::Point startp2; //四角形の始点 18cv::Point secondp2; //四角形の第2点 19cv::Point thirdp2; //四角形の第3点 20cv::Point endp2; //四角形の終点 21 22int p_count = 0; 23cv::Scalar line_color = cv::Scalar(0, 250, 0); // 線の色 (default 緑) 24cv::Scalar line_color2 = cv::Scalar(250, 0, 0); // 線の色 (default 赤) 25 26void onFourMouseClicks(int event, int x, int y, int flag, void *param) 27{ 28 using namespace cv; 29 Mat *mat = static_cast<Mat *>(param); // param は imageLine 30 imageL = mat->clone(); //マウス移動中の表示用画像 31 32 switch (event) 33 { 34 case cv::MouseEventTypes::EVENT_LBUTTONDOWN: //左ボタンが押されたら 35 if (p_count == 0 || p_count == 8) 36 { 37 std::cout << "始点:(" << x << " , " << y << ")" << endl; 38 39 imageP = results.clone();//枠線表示用画像 40 imageL = results.clone(); 41 startp.x = x; 42 startp.y = y; 43 p_count = 1; 44 break; 45 } 46 else if (p_count == 1) 47 { 48 std::cout << "第2点:(" << x << " , " << y << ")" << endl; 49 secondp.x = x; 50 secondp.y = y; 51 line(imageP, startp, secondp, line_color, 2); //1→2の直線描画 52 p_count = 2; 53 break; 54 } 55 else if (p_count == 2) 56 { 57 std::cout << "第3点:(" << x << " , " << y << ")" << endl; 58 thirdp.x = x; 59 thirdp.y = y; 60 line(imageP, secondp, thirdp, line_color, 2); //2→3直線描画 61 p_count = 3; 62 63 break; 64 } 65 else if (p_count == 3) 66 { 67 std::cout << "終点:(" << x << " , " << y << ")" << endl; 68 endp.x = x; 69 endp.y = y; 70 p_count = 4; 71 line(imageP, thirdp, endp, line_color, 2); //3→4直線描画 72 line(imageP, endp, startp, line_color, 2); //4→1直線描画 73 break; 74 } 75 else if(p_count == 4) 76 { 77 std::cout << "始点:(" << x << " , " << y << ")" << endl; 78 startp2.x = x; 79 startp2.y = y; 80 p_count = 5; 81 break; 82 } 83 else if(p_count == 5) 84 { 85 std::cout << "第2点:(" << x << " , " << y << ")" << endl; 86 secondp2.x = x; 87 secondp2.y = y; 88 line(imageP, startp2, secondp2, line_color2, 2); //1→2の直線描画 89 p_count = 6; 90 break; 91 } 92 else if(p_count == 6) 93 { 94 std::cout << "第3点:(" << x << " , " << y << ")" << endl; 95 thirdp2.x = x; 96 thirdp2.y = y; 97 line(imageP, secondp2, thirdp2, line_color2, 2); //2→3直線描画 98 p_count = 7; 99 break; 100 } 101 else if(p_count == 7) 102 { 103 std::cout << "終点:(" << x << " , " << y << ")" << endl; 104 endp2.x = x; 105 endp2.y = y; 106 p_count = 8; 107 line(imageP, thirdp2, endp2, line_color2, 2); //3→4直線描画 108 line(imageP, endp2, startp2, line_color2, 2); //4→1直線描画 109 110 pers = Mat::zeros(imageA.rows, imageA.cols, CV_8UC3); 111 // 左上、右上、右下、左下 が標準 112 const Point2f src_pt[] = { 113 Point2f(startp.x, startp.y), 114 Point2f(secondp.x, secondp.y), 115 Point2f(thirdp.x, thirdp.y), 116 Point2f(endp.x, endp.y)}; 117 const Point2f dst_pt[] = { 118 Point2f(startp2.x, startp2.y), 119 Point2f(secondp2.x, secondp2.y), 120 Point2f(thirdp2.x, thirdp2.y), 121 Point2f(endp2.x, endp2.y)}; 122 cv::Mat pers_mat = getPerspectiveTransform(src_pt, dst_pt); 123 // 射影変換行列pers_matにより,warpPerspectiveを用いて画像を変換 124 warpPerspective(imageA, pers, pers_mat, pers.size()); 125 imshow("mouse input window", imageP); 126 break; 127 } 128 case cv::MouseEventTypes::EVENT_MOUSEMOVE: 129 if (p_count == 1) 130 line(imageL, startp, Point(x, y), line_color, 2); //1→mouse直線描画 131 else if (p_count == 2) 132 line(imageL, secondp, Point(x, y), line_color, 2); //2→mouse直線描画 133 else if (p_count == 3) 134 line(imageL, thirdp, Point(x, y), line_color, 2); //3→mouse直線描画 135 else if (p_count == 5) 136 line(imageL, startp2, Point(x, y), line_color2, 2); //3→mouse直線描画 137 else if (p_count == 6) 138 line(imageL, secondp2, Point(x, y), line_color2, 2); //3→mouse直線描画 139 else if (p_count == 7) 140 line(imageL, thirdp2, Point(x, y), line_color2, 2); //3→mouse直線描画 141 //imshow("mouse input window", imageL); 142 break; 143 } 144} 145 146// マウスクリックした4点を4隅とするマスク画像(背景:黒(0),マスク:白(255))を生成する 147void makeMask(char **args) 148{ 149 imageA = cv::imread(args[0]); 150 if (imageA.empty()) 151 { 152 cout << "画像読み込み失敗" << endl; 153 return; 154 } 155 156 //クリック位置記憶用画像 157 imageP = imageA.clone(); 158 //マウス入力用画像 159 imageL = imageA.clone(); 160 //結果画像 161 results = imageA.clone(); 162 //マスク画像の初期化 163 mask = cv::Mat::zeros(imageA.size(), CV_8UC1); 164 165 //ウィンドウ作成 166 cv::namedWindow("mouse input window"); 167 168 cv::Mat images[] = {imageA, imageP, imageL}; 169 cv::setMouseCallback("mouse input window", onFourMouseClicks, (void *)&images); 170 171 //「q」が押されたら終了 172 while (true) 173 { 174 //画像の表示 175 cv::imshow("mouse input window", imageP); 176 switch (cv::waitKey(33)) 177 { 178 case 'c': 179 if (p_count == 8) 180 { // 4点クリックが終わっていたならば 181 mask = cv::Mat::zeros(results.size(), CV_8UC1); //マスク画像の0初期化 182 // vector<vector<cv::Point>> contour; //輪郭情報はPointの配列(ベクタ)の配列(ベクタ) 183 cv::drawContours(mask, vector<vector<cv::Point>>{{startp2, secondp2, thirdp2, endp2}}, 0, cv::Scalar::all(255), cv::FILLED); 184 cv::Mat srcA, srcB; 185 cv::resize(results, srcA, cv::Size(640, 480)); // BGRの3チャンネル画像 186 srcB = pers; // BGRの3チャンネル画像 187 188 cv::Mat result(cv::Size(srcA.cols, srcA.rows), CV_8UC3); 189 190 for (int y = 0; y < srcA.rows; y++) 191 { 192 uchar *p = srcB.ptr(y); 193 uchar *q = srcA.ptr(y); 194 uchar *m = mask.ptr(y); 195 uchar *r = result.ptr(y); 196 for (int x = 0; x < srcA.cols; x++) 197 { //マスクは1チャネル,他は3チャネル 198 r[x * 3] = p[x * 3] * m[x] / 255 + q[x * 3] * (255 - m[x]) / 255; 199 r[x * 3 + 1] = p[x * 3 + 1] * m[x] / 255 + q[x * 3 + 1] * (255 - m[x]) / 255; 200 r[x * 3 + 2] = p[x * 3 + 2] * m[x] / 255 + q[x * 3 + 2] * (255 - m[x]) / 255; 201 } 202 } 203 cv::imshow("Blending Result", result); 204 results = result; 205 p_count = 0; // 4点クリックは最初から 206 } 207 break; 208 case 'a': 209 imageP = results.clone(); 210 imageL = results.clone(); 211 cv::destroyWindow("Blending Result"); 212 p_count = 0; // 4点クリックは最初から 213 break; 214 case 's': // その時点の mask を保存 215 cv::imwrite("resultMasked.png", results); 216 cout << "saved to resultMasked.png" << endl; 217 break; 218 case 'R': // 最初に戻る 219 imageP = imageA.clone(); 220 imageL = imageA.clone(); 221 results = imageA.clone(); 222 p_count = 0; // 4点クリックは最初から 223 cv::destroyWindow("Blending Result"); 224 cout << "画像のリセット" << endl; 225 break; 226 case 'r': // 最初に戻る 227 imageP = results.clone(); 228 imageL = results.clone(); 229 p_count = 0; // 4点クリックは最初から 230 cv::destroyWindow("Blending Result"); 231 cout << "クリックのリセット" << endl; 232 break; 233 case 'q': 234 return; 235 } 236 } 237} 238 239int main(int argc, char *argv[]) 240{ 241 // makeMask関数に渡す配列の宣言 242 char *args[1] = {"imageA.jpg"}; 243 if (argc >= 2) 244 args[0] = argv[1]; //引数での入力画像指定 245 246 makeMask(args); 247 return 0; 248}

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

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

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

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

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

guest

回答1

0

自己解決

コマンド引数での指定の間違い、他画像の保存先の間違いなどが原因でした。
コード自体は問題ありませんでした。

投稿2020/07/27 03:36

nasu_nasu

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問