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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

758閲覧

OpenCV plus Unityを使って THETAでのリアルタイム画像処理を行いたいですが、画像データが正しく読み込めません

Go-Labstu

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2023/05/27 06:04

実現したいこと

・Unity内で360度カメラ THETA Z1を接続し、映像のリアルタイム画像処理を行いたい。
・画像処理にはOpenCVplusUnityを使用する。

前提

まず、THETAに接続して映像を表示するためコード 
参考:(https://qiita.com/reiya_prog/items/b52be9adf7a82a89eae0 )に
OpenCVを使って画像データを透視投影変換するプログラムを追加し、
THETAでリアルタイム画像処理を行うためのテストスクリプトを作成しました。

このスクリプトを平面に追加し、Playボタンを押して実行しましたが、カメラ映像は表示されず、以下のエラーメッセージが表示されました。

ちなみに
OpenCVの画像処理のプログラムを付け加える前の元のスクリプトでは、映像は問題なく表示できております。

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

エラーメッセージは以下の通りです。

C#

1OpenCVException: _src.total() > 0 2OpenCvSharp.NativeMethods+<>c.<.cctor>b__1286_0 (OpenCvSharp.ErrorCode status, System.String funcName, System.String errMsg, System.String fileName, System.Int32 line, System.IntPtr userdata) (at Assets/OpenCV+Unity/Assets/Scripts/OpenCvSharp/PInvoke/NativeMethods.cs:190) 3(wrapper native-to-managed) OpenCvSharp.NativeMethods+<>c.<.cctor>b__1286_0(OpenCvSharp.ErrorCode,intptr,intptr,intptr,int,intptr) 4OpenCvSharp.Cv2.WarpPerspective (OpenCvSharp.InputArray src, OpenCvSharp.OutputArray dst, OpenCvSharp.InputArray m, OpenCvSharp.Size dsize, OpenCvSharp.InterpolationFlags flags, OpenCvSharp.BorderTypes borderMode, System.Nullable`1[T] borderValue) (at Assets/OpenCV+Unity/Assets/Scripts/OpenCvSharp/Cv2/Cv2_imgproc.cs:984) 5LivePreview2+<GetLivePreview>d__2.MoveNext () (at Assets/Scripts/LivePreview2.cs:78) 6UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <86acb61e0d2b4b36bc20af11093be9a5>:0) 7UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) 8LivePreview2:Start() (at Assets/Scripts/LivePreview2.cs:13) 9

該当のソースコード

スクリプト名:LivePreview2

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Net; 5using System.IO; 6using OpenCvSharp; 7 8public class LivePreview2 : MonoBehaviour{ 9 // 取得した画像を適用するマテリアル 10 public Material view_material; 11 12 void Start(){ 13 StartCoroutine(GetLivePreview()); 14 } 15 16 IEnumerator GetLivePreview(){ 17 // POST先のURL。基本的には機種によらず同じURLで実行することができる 18 const string get_livepreview_URL = "http://192.168.1.1:80/osc/commands/execute"; 19 WebRequest livepreview_request = HttpWebRequest.Create(get_livepreview_URL); 20 livepreview_request.Method = "POST"; 21 livepreview_request.Timeout = 300000; 22 23 // POSTするjsonファイルの加工 24 livepreview_request.ContentType = "application/json;charset=utf-8"; 25 byte[] post_data = System.Text.Encoding.UTF8.GetBytes("{\"name\":\"camera.getLivePreview\"}"); 26 livepreview_request.ContentLength = post_data.Length; 27 28 // 通信開始 29 Stream request_stream = livepreview_request.GetRequestStream(); 30 request_stream.Write(post_data, 0, post_data.Length); 31 request_stream.Close(); 32 Stream response_stream = livepreview_request.GetResponse().GetResponseStream(); 33 34 BinaryReader response_reader 35 = new BinaryReader(new BufferedStream(response_stream), new System.Text.ASCIIEncoding()); 36 List<byte> picture_data = new List<byte>(); 37 bool is_load_start = false; 38 39 // MotionJPEGで送信される画像データを受け取り次第テクスチャとして適用させ続ける 40 while (true){ 41 byte byte_data = response_reader.ReadByte(); 42 if (!is_load_start){//画像データの先頭を捜索中 43 // MotionJPEGの先頭2バイトは0xFFD8 44 if (byte_data == 0xFF){ 45 byte next_data = response_reader.ReadByte(); 46 if (next_data == 0xD8){ 47 // MotionJPEGの先頭2バイトの確認ができたので、画像データとして取得開始 48 picture_data.Add(byte_data); 49 picture_data.Add(next_data); 50 51 is_load_start = true; 52 } 53 } 54 }else{ 55 picture_data.Add(byte_data); 56 // MotionJPEGの末尾2バイトは0xFFD9 57 if (byte_data == 0xFF){ 58 byte next_data = response_reader.ReadByte(); 59 if (next_data == 0xD9){ 60 // MotionJPEGの末尾2バイトの確認が出来たので、画像データをまとめてテクスチャとして適用 61 picture_data.Add(next_data);//データの追加 62 63 //追加ここから 64 65 // 画像データをMatオブジェクトに変換 66 Mat srcMat = new Mat(); 67 Cv2.ImDecode(picture_data.ToArray(), ImreadModes.Color);//画像データの読み込み 68        //picture_data.というリストを配列に変換し カラーで読み込み 69 70 // 透視投影変換の行列を作成 71 Mat perspectiveMatrix = Cv2.GetPerspectiveTransform( 72 new Point2f[4] { new Point2f(0, 0), new Point2f(srcMat.Width, 0), new Point2f(srcMat.Width, srcMat.Height), new Point2f(0, srcMat.Height) }, 73 new Point2f[4] { new Point2f(100, 100), new Point2f(srcMat.Width - 100, 100), new Point2f(srcMat.Width - 100, srcMat.Height - 100), new Point2f(100, srcMat.Height - 100) } 74 ); 75 76 // 透視投影変換を適用 77 Mat perspectiveMat = new Mat(); 78 Cv2.WarpPerspective(srcMat, perspectiveMat, perspectiveMatrix, srcMat.Size()); 79 80 // MatをTexture2Dに変換 81 Texture2D sphereTexture = new Texture2D(perspectiveMat.Width, perspectiveMat.Height, TextureFormat.RGBA32, false); 82 OpenCvSharp.Unity.MatToTexture(perspectiveMat, sphereTexture); 83 84 // テクスチャとして適用 85 Destroy(view_material.mainTexture); 86 view_material.mainTexture = sphereTexture; 87 88 //追加ここまで 89 90 Texture2D sphere_texture = new Texture2D(1, 1); 91 sphere_texture.LoadImage((byte[])picture_data.ToArray()); 92 Destroy(view_material.mainTexture); // 書いておかないと無限にテクスチャが増えてメモリリークする 93 view_material.mainTexture = sphere_texture; 94 picture_data.Clear(); 95 System.GC.Collect(); 96 is_load_start = false; 97 yield return null; 98 }else{ 99 picture_data.Add(next_data); 100 } 101 } 102 } 103 } 104 } 105} 106

ちなみに、インポートのusing OpenCvSharp;の部分と
63行目から88行目までが、THETAに接続して映像を表示するためのコード
参考:(https://qiita.com/reiya_prog/items/b52be9adf7a82a89eae0 )に追加した部分です。

試したこと

変換前の画像データを格納するsrcMatが空ではないのかと仮定して、画像データを読み込むためのメソッドであるCv2.ImDecodeを

67行目
Cv2.ImDecode(picture_data.ToArray(), ImreadModes.Color); 
に第三引数としてsrcMatを追加して
Cv2.ImDecode(picture_data.ToArray(), ImreadModes.Color, srcMat);
と修正しましたが

以下のようにエラーが出ました。

No overload for method 'ImDecode' takes 3 arguments

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

OpenCV plus Unity Unity2021.3.11f1

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

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

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

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

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

guest

回答1

0

自己解決

OpenCVの基礎的な部分が理解できていなかったため、それらについて勉強することで、結果として解決できました。

投稿2023/07/10 01:37

Go-Labstu

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問