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

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

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

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

C++

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

Q&A

解決済

1回答

654閲覧

二次元配列にカラー画像のBGR成分を格納したい

beginner_prog

総合スコア3

OpenCV

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

C++

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

0グッド

0クリップ

投稿2022/11/01 05:39

編集2022/11/01 17:05

質問内容

C++とopenCVを用いて2枚のカラー画像(.bmp)を読み込み,それぞれBGRの値をvectorで作ったバッファーに格納するプログラムを作成したいです.それぞれBGRの分離はopenCVのsplitを使っています.また読み込む画像のサイズは同じで,8bitRGB画像です.

イメージとしては,一枚目の画像のBGRはそれぞれ,
image[0][0] //BのMatデータ
image[0][1] //GのMatデータ
image[0][2] //RのMatデータ

に格納して二枚目の画像のBGRはそれぞれ
image[1][0] //BのMatデータ
image[1][1] //GのMatデータ
image[1][2] //RのMatデータ

に格納したいという感じです.

添付のコードのように作成しようとしていました.
作成したvetorのバッファーが1次元目と2次元目両方とものMat型になっているのでエラーが出るのはわかるのですが,vectorの型指定を別々する方法などがわからなくて困っています.
また,できないとしたらどのような方法で格納することができるか教えていただきたいです.

初歩的な質問だと思いますが,よろしくお願いいたします.

出てきたエラー

イメージ説明

該当のソースコード

C++,openCV

1 2vector<Mat>a(2); 3 4a[0] = imread("input_image1.bmp"); 5a[1] = imread("input_image2.bmp"); 6 7vector<vector<Mat>>image; 8 9for(int i = 0; i<2; i++){ 10 split(a[i],images[i]); 11} 12

補足情報(FW/ツールのバージョンなど)

C++
VisualStudio2019
openCV4.5.3

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

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

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

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

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

PondVillege

2022/11/01 06:51 編集

どういうエラーが出たのか明記いただけますでしょうか? vector<vector<Mat>> image; としているあたり,後のimage[i]で配列の範囲外アクセスによるエラーが生じるものと思われます.
beginner_prog

2022/11/01 07:07 編集

お返事ありがとうございます. 出てきたエラーを記載させていただきました. ps_aux_grepさんのおっしゃる通り,範囲外アクセスによるエラーです. 私としては,image[int型][Mat型]にしたいと考えているのですが,定義方法をご存じでしょうか. いくつか調べてみたのですが,検索方法が下手で解決策を見つけることができませんでした. よろしくお願いいたします.
PondVillege

2022/11/01 07:14

> image[int型][Mat型]にしたいと考えているのですが,定義方法をご存じでしょうか. vector<map<Mat, Mat>>にしたらできるんじゃないですか? でも違うと思ったので解答は Mat型 == image[int型][int型] であるような状態ですがどうでしょう.
beginner_prog

2022/11/01 07:28

お返事ありがとうございます. このような初歩的な質問にもかかわらず,丁寧に教えていただきとても助かりました. 最後に一つお聞きしたいことがあります. 調べていた時に以下のようなものを見つけました. std::vector<std::vector<型名> > 変数名(要素数,vector<型名>(要素数); こちらのコードでは,型名が一方しか定義されていないように思われます.この場合,定義されていないものはどのように定まるのでしょうか.
fana

2022/11/01 07:34

そもそも 2*3 個である(画像が2枚で,1画像が3ch)と分かっている状況下において vector とか持ち出してくる必要自体が無いのではあるまいか: cv::Mat Image[2][3]; //要は計6個のMatがあればいいんでしょ?
PondVillege

2022/11/01 07:57 編集

それは二次元vectorの完全な初期化ですね. > こちらのコードでは,型名が一方しか定義されていないように思われます.この場合,定義されていないものはどのように定まるのでしょうか. 言っている意味があまりわかりません.配列は [ ] の中に整数しか受け入れず,格納するデータは何でも良い.という前提からでは出てこない疑問に思います. bracket operatorに任意のオブジェクトを受け取って格納しているものを返したいなら,それこそ先述のようにmapを使うべきでしょう. std::vector<std::vector<型名> > 変数名(要素数,vector<型名>(要素数); をusingを使って書き換えると using v = vector<型名>; using vv = vector<v>; vv 変数名(要素数, v)(要素数, 初期値); になります. もしimage[int型][Mat型]と書いてMat型を得たいなら,先述の通り vector<map<Mat, Mat>> で変数宣言してください.
beginner_prog

2022/11/01 07:43

fanaさん お返事ありがとうございます. もともとそのようにしていたのですが,要素数に変数をもちいたかったのでvectorを使う検討をしていました.Mat Image[2][3]の要素数を変数にする方法をご存じでしたら教えていただけると幸いです.
beginner_prog

2022/11/01 07:45

ps_aux_grepさん お返事ありがとうございます. 明らかに自分の知識不足による勘違いでした.とても丁寧に教えていただきありがとうございます.
fana

2022/11/01 07:49

「2枚の画像を読込んで~」という話なのに,要素数をわざわざ変数にしたいという意味がわからないが… あえてvectorにしたいという話であれば既に回答が付いてるし.
fana

2022/11/01 07:53

vector< vector<Mat> > とか書いた時点で何か混乱が生じるということなのであれば, 「1枚の画像用のデータ(:chをバラした結果データ)」っていう型でも用意して, vector< その型 > っていう形にすれば見通しが良いんじゃない? (わざわざ型を用意するのはなぁ…っていうなら,↑で示されているように using で別名を付けるだけでもいいし)
beginner_prog

2022/11/01 08:02 編集

fanaさん お返事ありがとうございます. 大変分かりやすい解説で初心者の私にとってはとてもありがたいです. また,質問文につきましては大変申し訳ありませんでした.以後,前提の明記は漏れがないように行います. ご指摘いただきありがとうございました.
fana

2022/11/01 08:01

「どのデータが何番目の要素に来るのか?」っていうルールさえしっかり決めて運用しさえすれば vector< Mat > Image( 6 ); //6個 という1次元で持つのでも良いんじゃないか,とか.
beginner_prog

2022/11/01 08:05 編集

fana さん 確かにおっしゃる通りだと思います. 初めから高度なプログラムを書くよりも,まずは簡単な方法を試すべきですね. fanaさんにお答えしていただけて本当に助かりますし勉強になりました. ありがとうございました.
guest

回答1

0

ベストアンサー

サイズ不足による範囲外アクセスが起きたなら,サイズをきちんと設定するのみです.

C++

1vector<vector<Mat>> image(2); // サイズ2で初期化, 初期値は第二引数に渡せる 2for (int i = 0; i < 2; i++) { 3 split(a[i], image[i]); 4}

投稿2022/11/01 07:10

PondVillege

総合スコア1579

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問