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

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

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

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

C++

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

Q&A

3回答

1609閲覧

OpenCVのimwriteがnullになる

Takumi_s

総合スコア13

OpenCV

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

C++

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

0グッド

0クリップ

投稿2018/07/06 20:56

編集2018/07/06 21:02

発生している問題

imshow で表示できている画像情報が imwrite で保存できません.

以下の機能を持つプログラムを作成しました.

  1. ドラッグ&ドロップしたディレクトリ(inputDir)の直下にディレクトリ(outputDir)を作成
  2. inputDir内の画像を読み込みリサイズし,outputDir 内に保存

しかしながら,現状,outputDir 内に空のファイルが作成されるのみとなっています.

また,複数の画像ファイルが存在しているディレクトリを入力しても,処理が 1 枚分で止まっているようです.

なので,正しく動作するためにはどう修正すればよいかお教え願います.

試したこと

  • imwrite を除いた状態で imshow で dst を表示 -> 正常に処理される

環境

  • Microsoft windows 10 64bit
  • Visual Studio 2013 Ultimate
  • OpenCV_3.0.0

参考にしたサイト

プログラム

c++

1#define _CRT_SECURE_NO_WARNINGS 2 3#include <Windows.h> 4#include <direct.h> 5#include <stdexcept> 6#include <iostream> 7#include <vector> 8#include <string> 9#include <opencv2/opencv.hpp> 10 11using namespace std; 12using namespace cv; 13 14string inputDir; 15 16vector<string> getImageName(string dir_name); 17 18int main(int argc, char* argv[]) 19{ 20 // 入力ディレクトリの取得 21 if (argc > 1) { 22 inputDir = argv[1]; 23 cout << "input directory : " << inputDir << endl; 24 } 25 else { 26 cerr << "no input file" << endl; 27 while (1) {}; 28 return -1; 29 } 30 31 size_t length = inputDir.length(); 32 //cout << "length : " << length << endl; 33 34 while (true) { 35 auto pos = inputDir.find("\"); 36 if (pos == -1) break; 37 38 inputDir.replace(pos, 1, "/"); 39 //cout << "pos : " << pos + 1 << endl; 40 } 41 42 string dir = inputDir + "/"; 43 string outputDir = dir + "resized"; 44 45 try { 46 if (_mkdir(outputDir.c_str()) == 0){ 47 cout << "success create dir : " << outputDir << endl; 48 } 49 else{ 50 cout << "do not create." << endl; 51 } 52 } 53 catch (...) { 54 cout << "input error" << endl; 55 while (1) {}; 56 } 57 58 // ファイル内の画像名の取得 59 vector<string> file_names = getImageName(dir); 60 61 // 表示・保存部分 62 string filePath; 63 for (auto f : file_names) { 64 //cout << f << endl; 65 66 string fileName = f.c_str(); 67 //cout << "fileName : " << fileName << endl; 68 string filePath = dir + fileName; 69 //cout << "filePath : " << filePath << endl; 70 Mat src = imread(filePath); 71 Mat dst; 72 73 resize(src, dst, Size(227, 227), 0, 0, INTER_LINEAR); 74 75 string outputPath = outputDir + "/" + fileName; 76 cout << "output file path : " << outputPath << endl; 77 78 imshow("img", dst); 79 waitKey(30); 80 81 imwrite(outputPath, dst); 82 waitKey(30); 83 } 84 85 system("pause"); 86 return 0; 87} 88 89// inputDir内にある画像名を取得する 90vector<string> getImageName(string dir_name) { 91 92 HANDLE hFind; 93 WIN32_FIND_DATA win32fd; 94 std::vector<std::string> file_names; 95 96 // png,jpg,bmpの拡張子のファイルのみを読み込む 97 std::string extension[3] = { "png", "jpg", "bmp" }; 98 99 for (int i = 0; i < 3; i++) { 100 101 string search_name = dir_name + "*." + extension[i]; 102 hFind = FindFirstFile(search_name.c_str(), &win32fd); 103 104 if (hFind == INVALID_HANDLE_VALUE) { 105 continue; 106 } 107 do { 108 109 if (win32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 110 } 111 else { 112 file_names.push_back(win32fd.cFileName); 113 } 114 } while (FindNextFile(hFind, &win32fd)); 115 116 FindClose(hFind); 117 } 118 119 return file_names; 120}

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

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

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

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

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

guest

回答3

0

こんにちは。

Visual Stuido 2017 + OpenCV 3.2でやってみましたが、問題なく動作しました。
ファイル名のパスに日本語が含まれていると正常動作しなことがあります。
jpgファイル等を日本語が含まれないパスに保存してトライしてみるとうまくいくかも知れません。

投稿2018/07/07 05:50

Chironian

総合スコア23272

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

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

0

コードを読む限り、FindFirstFileの結果くらいしか疑うところは無さそうです。
パッと思いつく可能性としては、Unicode版が動作してて、win32fd.cFileNameがwstringになっている、など。

投稿2018/07/07 02:07

kazto

総合スコア7196

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

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

0

cv::imwriteのドキュメントのサンプルによると
cv::imwriteは例外を投げる可能性があるようです。

とりあえず、例外を記録してみましょう。

lang

1try { 2 imwrite(outputPath, dst); 3} catch (runtime_error& ex) { 4 cerr << "Exception:" << ex.what() << endl; 5 cerr << "at " << outputPath << endl; 6}

投稿2018/07/07 01:16

asm

総合スコア15147

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問