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

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

ただいまの
回答率

87.48%

RenderTextureによって取得した画像をOpenCVforUnityによって射影変換し,ゲームオブジェクトのテクスチャの上に貼り付けたい.

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 835

score 20

前提・実現したいこと

RenderTextureによって取得した画像をOpenCVforUnityによって射影変換し,ゲームオブジェクトのテクスチャの上に貼り付けたい.

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

インスペクタでは,射影変換後の画像が貼り付けられているが,実際のオブジェクトにはテクスチャが適用されず,灰色になる.

処理の流れ

  1. カメラが撮影している領域をRenderTextureによって取得(領域をAとする)
  2. ReadPixelsによってAをTexture2D型に変換
  3. texture2DToMatによって,AをMat型に変換
  4. getPerspectiveTransformによって,Aを任意の形に射影変換(射影変換後をBとする)
  5. 貼り付けるゲームオブジェクトのテクスチャを背景画像として取得(背景画像をCとする)
  6. CopyToによって,BをCに貼り付ける.
  7. matToTexture2Dによって,CをTexture2D型に変換
  8. gameObject.GetComponent<Renderer>().material.mainTexture = B によって,メインテクスチャをBに変更する.

実行画面

図1が実行前の画面で,説明を表記している.
図2が実行時の画像である.
図2のインスペクタ右下の円を見ると,CapturedFieldにカメラで撮影した領域の一部が射影変換されて,写っていることがわかる.しかし,殆どの部分が灰色で覆われている上に,右下の円を回転させると,写っている領域と,灰色の領域が変わっていく.
イメージ説明
図1. 画面の説明
イメージ説明
図2. 実行時の画像

画像をキャプチャ後CapturedFieldに貼り付ける処理(処理の流れ3 ~ 8)

using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;
using UnityEngine;
using static OpenCVForUnity.CoreModule.CvType;
using Rect = OpenCVForUnity.CoreModule.Rect;

public class PasteTexture : MonoBehaviour
{
    private GameObject capturedField;
    Texture2D backGroundOnTex2D;


    //captionOnTex2D : 撮影した画像
    //vertices : 射影変換後の4点
    public Texture2D pastePhoto(Texture2D captionOnTex2D, Mat[] vertices)
    {
        //                                      初期化                                      //

        //貼付け後の画像の背景
        backGroundOnTex2D = capturedField.GetComponent<Renderer>().material.mainTexture as Texture2D;
        //貼付け後の画像の背景のMat
        Mat backGroundOnMat = new Mat(backGroundOnTex2D.height, backGroundOnTex2D.width, CV_8UC4);
        //貼付け後の画像の背景をMatに変換
        Utils.texture2DToMat(backGroundOnTex2D, backGroundOnMat);

        //撮影した画像のMat
        Mat captionOnMat = new Mat(captionOnTex2D.height, captionOnTex2D.width, CV_8UC4);
        //キャプションをMatに変換
        Utils.texture2DToMat(captionOnTex2D, captionOnMat);

        //射影変換後の画像
        Mat transformedMat = new Mat(backGroundOnTex2D.height, backGroundOnTex2D.width, CV_8UC4);
        //出力画像
        Texture2D dst2D = new Texture2D(backGroundOnTex2D.height, backGroundOnTex2D.width);
        //Debug.Log("yet "+ transformedMat);

        //キャプチャ画像の4点
        Mat pointCaption = new Mat(4, 1, CvType.CV_32FC2);
        pointCaption.put(0, 0,
            0.0, 0.0,
            0.0, captionOnTex2D.height,
            captionOnTex2D.width, captionOnTex2D.height,
            captionOnTex2D.width, 0.0);

        //回転後の4点
        Mat pointVertices = new Mat(4, 1, CvType.CV_32FC2);
        pointVertices.put(0, 0,
            vertices[0].get(0, 0)[0], vertices[0].get(2, 0)[0],
            vertices[1].get(0, 0)[0], vertices[1].get(2, 0)[0],
            vertices[2].get(0, 0)[0], vertices[2].get(2, 0)[0],
        vertices[3].get(0, 0)[0], vertices[3].get(2, 0)[0]);

        //                                      処理                                      //

        //射影変換
        transformedMat = projectiveTransform(pointCaption, pointVertices, captionOnMat);

        //ROI指定
        Rect rect = new Rect(0, 0, transformedMat.cols(), transformedMat.rows());
        Mat Roi1 = new Mat(backGroundOnMat, rect);

        //背景に射影変換後の画像を貼り付け
        transformedMat.copyTo(Roi1);

        //貼り付けた画像をTex2Dに変換
        Utils.matToTexture2D(backGroundOnMat, dst2D);

        //テクスチャに適用する
        capturedField.GetComponent<Renderer>().material.mainTexture = dst2D;
    }

    Mat projectiveTransform(Mat pointCaption, Mat pointVertices, Mat captionOnMat)
    {

        Mat transformedMat = new Mat();

        //変換行列作成
        Mat matrix = Imgproc.getPerspectiveTransform(pointCaption, pointVertices);

        //射影変換
        Imgproc.warpPerspective(captionOnMat, transformedMat, matrix, captionOnMat.size());

        return transformedMat;
    }
}

試したこと

撮影した画像をそのまま,貼り付けると成功した.

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

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

  • ただいまの回答率 87.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Unityに関する質問
  • RenderTextureによって取得した画像をOpenCVforUnityによって射影変換し,ゲームオブジェクトのテクスチャの上に貼り付けたい.