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

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

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

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

4472閲覧

Visual Basic x OpenCVSharp4でGetIndexer()を使用したMatへのアクセスを行いたい

lemongrass

総合スコア18

OpenCV

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2020/07/25 08:24

編集2020/07/26 08:37

前提・実現したいこと

Visual Basic.NETでOpenCVSharpを使用し、画像認識による自動化ソフトを作成しています。
機能の1つを実装するために、GetIndexer()を使用してMatのピクセルデータにアクセスするコードを書いています。
現在OpenCVSharp 4.1.0.20190416を使用しており、最新バージョン(4.4.0.20200725)にアップデートしようとしたところ、以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

Error

1エラー BC32044 型引数 'Vec3b' は、制約型 '?' から継承したり、この型を実装したりしません。 2エラー BC30649 '' の型はサポートされていません。

該当のソースコード

VBNET

1'Version 4.1.0.20190416 2Dim src As Mat = New Mat("xxx.png", ImreadModes.AnyColor) 3 4Dim matofbyte_tpl As MatOfByte3 = New MatOfByte3(src) 5Dim indexer_tpl As MatIndexer(Of Vec3b) = matofbyte_tpl.GetIndexer() 6 7For y = 0 To src.Height - 1 8 For x = 0 To src.Width - 1 9 10 '各ピクセルのRGB値を取得 11 Dim rgb As Vec3b = indexer_tpl(y, x) 12 Debug.WriteLine("R:{0}, G:{1}, B:{2}", rgb(2), rgb(1), rgb(0)) 13 14 Next 15 16Next 17 18 19'Version 4.4.0.20200725 20Dim src As Mat = New Mat("xxx.png", ImreadModes.AnyColor) 21 22Dim matofbyte_tpl As Mat(Of Vec3b) = New Mat(Of Vec3b)(src) 'この行でエラーが発生します。 23Dim indexer_tpl As MatIndexer(Of Vec3b) = matofbyte_tpl.GetIndexer() 24 25For y = 0 To src.Height - 1 26 For x = 0 To src.Width - 1 27 28 '各ピクセルのRGB値を取得 29 Dim rgb As Vec3b = indexer_tpl(y, x) 30 Debug.WriteLine("R:{0}, G:{1}, B:{2}", rgb(2), rgb(1), rgb(0)) 31 32 Next 33 34Next

試したこと

バージョン4.1.0.20190416から4.1.1.20191017へのアップデートで使用できなくなったことを確認しました。
OpenCVSharpのコミットを見てみると、MatOfXXXというクラス?が削除され、以下のように記述するようになったようです。
https://github.com/shimat/opencvsharp/compare/4.1.0.20190417...4.1.1.20191023

C#

1- using (var imgt = new MatOfByte3(img)) 2+ using (var imgt = new Mat<Vec3b>(img))

C#で記述したところ正常に動作することを確認できたので、VB.NETでの書き方に問題があると考えています。

C#

1Mat src = new Mat("xxx.png", ImreadModes.AnyColor); 2Mat<Vec3b> matofbyte_tpl = new Mat<Vec3b>(src); 3MatIndexer<Vec3b> indexer_tpl = matofbyte_tpl.GetIndexer(); 4 5for (int y = 0; y < src.Height; y++) 6{ 7 for (int x = 0; x < src.Width; x++) 8 { 9 Vec3b rgb = indexer_tpl[y, x]; 10 11 Debug.WriteLine("R:{0}, G:{1}, B:{2}",rgb[2],rgb[1],rgb[0]); 12 13 } 14}

エラー内容を調べ、解決方法も見てみたのですが、型パラメーターに指定されたすべてのインターフェイスを実装し~ や、サポートされる型を使用、新しい型を開発等と書かれており、理解が及ばず質問させていただいた次第です。

よろしくお願いいたします。

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

開発環境
VisualStudio 2019
VisualBasic
Microsoft .Net Framework 4.7.2

追記(2020-07-26 13:26)

以下のコードでもMatへのアクセス(RGB値の取得)を行うことができました。シンタックスハイライトが少しおかしいような…?

VBNET

1'Imports System.Runtime.InteropServices 2'Imports OpenCvSharp 3 4Dim src As Mat = Cv2.ImRead("xxx.png", ImreadModes.AnyColor) 5Dim bgr As Byte() = New Byte(3 * src.Total() - 1) {} '画像のピクセル数xチャンネル数分のByte配列を確保する。 6 7Marshal.Copy(src.Data, bgr, 0, bgr.Length) 8 9For i = 0 To bgr.Length - 1 Step 3 10 '(B,G,R)=(255,0,0)…全体を青色にしてみる 11 bgr(i) = 255 'B 12 bgr(i + 1) = 0 'G 13 bgr(i + 2) = 0 'R 14 15Next 16 17Marshal.Copy(bgr, 0, src.Data, bgr.Length) 18 19Cv2.ImShow("Result", src)

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

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

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

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

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

guest

回答1

0

ベストアンサー

自分もOpenCV初心者で最新バージョンを使っていないため、動かなかったら申し訳ございませんが、

VB

1Dim src As Mat = Cv2.ImRead("xxx.png", ImreadModes.AnyColor) 2Dim indexer_tpl As Mat.Indexer(Of Vec3b)=src.GetGenericIndexer(Of Vec3b) 3For y = 0 To src.Height - 1 4 For x = 0 To src.Width - 1 5 Dim rgb As Vec3b = indexer_tpl(y, x) 6 '処理 7 Next 8Next

で問題なく動作しませんか?

加えて、New Mat()で画像読み込んでも、実際にちゃんとデーターが読み込まれているか確認しましたか?(自分の場合は読み込まれていないことが多かったです。原因不明。)

追記(2020-07-26 13:26)とコメントに対するコメント(2020-07-26 15:53)

追加情報のお知らせありがとうございます。どうでもいいことかもしれませんが、RGB値読んで簡単な処理をするだけならOpenCvSharpを導入するまでもなく同じようにバイト配列読む方法で、System.Drawing(GDI+であってるかな)でできるので念のため載せておきます。

VB.NET

1Imports System.Runtime.InteropServices 2Using bmp As New Bitmap("xxx.png") 3 Dim bmpData1 As Imaging.BitmapData = bmp.LockBits(New Rectangle(Point.Empty, bmp.Size), Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb) 4 Dim pix1 As IntPtr = bmpData1.Scan0 5 Dim dataLength As Integer = bmpData1.Stride * bmpData1.Height 6 For i = 0 To dataLength - 1 Step 4 7 Dim c As Color = Color.FromArgb(Marshal.ReadByte(pix1, i + 3), Marshal.ReadByte(pix1, i + 2), Marshal.ReadByte(pix1, i + 1), Marshal.ReadByte(pix1, i)) 8 Next 9 bmp.UnlockBits(bmpData1) 10End Using

投稿2020/07/26 01:28

編集2020/07/26 06:54
Shalterier

総合スコア9

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

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

lemongrass

2020/07/26 03:01 編集

回答ありがとうございます。 GetGenericIndexer()を使用して、4.4.0.20200725で稼働することを確認できました。ありがとうございます! 私の環境ではNew Mat()で特に問題なく読み込めていましたが、Imreadを使ったほうが良いようですね(実際のアプリではImreadを使用していたのになんでNew Mat()で書いたんだろう…)。 処理速度を見てみましたが、GetIndexer()とGetGenericIndexer()それぞれの処理速度を100回ループした平均で見てみると、大体3倍ちょっとGetIndexerを使用したほうが早い結果となりました。実用上問題なければバージョンアップ、あれば現在のバージョンを使い続けていこうと思います。 (同バージョンで比較したいためC#、画像サイズ:630x360  GetIndexer()→22ms  GetGenericIndexer()→72ms) Mat<Vec3b>がVB.NETで使用できないのは、(もし記述方法があっていれば)C#の仕様変更にVB.NETがサポートできていないことが理由なのではとOpenCVSharpのIssueを見てふと思いました。 https://github.com/shimat/opencvsharp/issues/911
lemongrass

2020/07/26 04:25

↑のIssueの助言を頼りに調べてみたところ、高速にRGB値を得ることができました(コードは質問内容に追記いたしました)。RGB値を得るだけでも色々な手法がありますね…
lemongrass

2020/07/26 08:49

追記コメント、GDI+を利用した方法についての記載ありがとうございます。 後出しになってしまいますが、画像認識を具体的に書くと2枚の画像…デスクトップ上の画面をキャプチャした画像と事前にキャプチャした画像(テンプレート)を比較するもので、RGB値を利用したものの他にテンプレートマッチングやヒストグラム、AKAZE等様々な種類の比較ができるように作成しています。前処理の時点で画像を既にMatに変換している為、MatのままRGB値を取得しよう、ということで制作していました(プロフィールに一応制作物へのURLを貼っておきます…恥ずかしいので適当なタイミングで削除します)。 今後またなにか作るときには参考にさせていただきます。 (Marshal.Copyを使用したコードをStepを使った方法に書き換えました。喜びに舞い上がってて)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問