🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

2回答

9967閲覧

Unityで、クリックしたピクセルの色を取得したい

hokusou7500

総合スコア18

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2019/11/05 06:18

前提・実現したいこと

Unityで、ウェブカメラで読み込んだ画像をクリックしてそのクリックしたピクセルの色を取得するというものを作っています。

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

ウェブカメラで映像を映し出し、クリックしたピクセルのカラーコードを表示するというところまでいったのですが表示しているカラーコードが明らかにクリックしたピクセルの色ではないカラーコードになってしまっています。
実行画面
この画像は実行してみたところになります。ポインタが指すところをクリックしたところで、右のパネルに取得した色を表示しています。このように、白っぽい部分をクリックしているにも関わらず実際に表示された色はグレーに近い色になってしまっています。

該当のソースコード

以下がこのプロジェクトで使用しているスクリプトのソースコードになります。

WebCameraTest

1using UnityEngine; 2using UnityEngine.UI; 3 4public class WebCameraTest : MonoBehaviour 5{ 6 public RawImage rawImage; 7 8 WebCamTexture webCamTexture; 9 10 11 void Start() 12 { 13 webCamTexture = new WebCamTexture(); 14 rawImage.texture = webCamTexture; 15 webCamTexture.Play(); 16 } 17 18 // Update is called once per frame 19 void update () 20 { 21 22 } 23}

GetColor

1using UnityEngine; 2 3 4public class GetColor : MonoBehaviour 5{ 6 public Color color; 7 private Texture2D tex = null; 8 9 void Start() 10 { 11 tex = new Texture2D(1,1, TextureFormat.RGB24, false); 12 } 13 14 public void Onclick() 15 { 16 Vector2 pos = Input.mousePosition ; 17 tex.ReadPixels(new Rect(pos.x, pos.y, 1, 1), 0, 0); 18 color = tex.GetPixel(0,0); 19 Debug.Log(color); 20 } 21} 22

UpdateColor

1using UnityEngine; 2 3public class UpdateColor : MonoBehaviour 4{ 5 private GetColor getColor; 6 7 void Start() 8 { 9 getColor = GameObject.FindObjectOfType<GetColor>(); 10 } 11 12 // Update is called once per frame 13 void Update() 14 { 15 GetComponent<Renderer>().material.color = getColor.color; 16 Debug.Log(getColor.color); 17 Debug.Log(GetComponent<Renderer>().material.color); 18 string save_1_color = ColorUtility.ToHtmlStringRGB(getColor.color); 19 Debug.Log(save_1_color); 20 } 21}

WebCameraTestおよびGetColorはRawImageに、UpdateColorはPlaneにアタッチしてあります。
構成

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

Unity 2019.2.9f1、VisualStudio2015での開発です。

何卒ご教授のほどよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

間違っていたらすみません。
Input.mousePositionとReadPixelsの座標系が違うせいで狙ったのと違うピクセルを拾っているのではないでしょうか。

投稿2019/11/05 12:13

175

総合スコア147

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

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

0

ベストアンサー

Input.mousePositionの位置からtex.ReadPixelsで色を取っていることから察しますに、もしかしてWebCamTexture上からだけでなく画面全体から色を取る必要があるのでしょうか?
もしそうでしたら、色取りのタイミングを変えてやるといいかもしれません。

C#

1using System.Collections; 2using UnityEngine; 3 4public class GetColor : MonoBehaviour 5{ 6 public Color color; 7 private Texture2D tex = null; 8 9 void Start() 10 { 11 tex = new Texture2D(1, 1, TextureFormat.RGB24, false); 12 } 13 14 public void OnClick() 15 { 16 StartCoroutine(GetColorCoroutine()); 17 } 18 19 private IEnumerator GetColorCoroutine() 20 { 21 // 色取得メソッドをコルーチン化し、実際の色取得をフレーム末尾まで遅延させて 22 // 画面のレンダリングが完了してから色を取得するようにする 23 yield return new WaitForEndOfFrame(); 24 Vector2 pos = Input.mousePosition; 25 tex.ReadPixels(new Rect(pos.x, pos.y, 1, 1), 0, 0); 26 color = tex.GetPixel(0, 0); 27 Debug.Log(color); 28 } 29}

それともWebCamTexture上だけに絞った方が望ましいでしょうか?
その場合は、下記のように色取り方法を変更してみてはいかがでしょう。

C#

1using UnityEngine; 2using UnityEngine.UI; 3 4public class GetColor : MonoBehaviour 5{ 6 public Color color; 7 8 // texは使用しない 9 // private Texture2D tex = null; 10 11 void Start() 12 { 13 // texは使用しない 14 // tex = new Texture2D(1, 1, TextureFormat.RGB24, false); 15 } 16 17 public void OnClick() 18 { 19 // Input.mousePositionはゲーム画面全体の中でのマウスポインタの位置を示しているので 20 // RawImageに映されているWebCamTextureから正しく色を取るにはそのままでは使えず、座標変換が必要なはず 21 Vector2 pos = Input.mousePosition; 22 23 // まず自分自身のRectTransform...つまりRawImageのRectTransformを取得し... 24 RectTransform rectTransform = transform as RectTransform; 25 26 // 自分自身が所属しているCanvasも取得し... 27 Canvas rootCanvas = rectTransform.GetComponentInParent<Canvas>().rootCanvas; 28 29 // posを自分自身のローカル座標に直して... 30 RectTransformUtility.ScreenPointToLocalPointInRectangle( 31 rectTransform, 32 pos, 33 rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : rootCanvas.worldCamera, 34 out Vector2 localPos); 35 36 // さらにUV座標に換算し... 37 Rect rect = rectTransform.rect; 38 Vector2 uv = (localPos - rect.position) / rect.size; 39 40 // RawImage経由でWebCamTextureのサイズを調べ... 41 WebCamTexture webCamTexture = this.GetComponent<RawImage>().texture as WebCamTexture; 42 Vector2Int webCamTexSize = new Vector2Int(webCamTexture.width, webCamTexture.height); 43 44 // UV座標をピクセル単位の位置に換算し... 45 Vector2 texPos = uv * webCamTexSize; 46 Vector2Int texPosInt = new Vector2Int( 47 Mathf.Clamp((int)texPos.x, 0, webCamTexSize.x - 1), 48 Mathf.Clamp((int)texPos.y, 0, webCamTexSize.y - 1)); 49 50 // WebCamTextureから色を取得する 51 color = webCamTexture.GetPixel(texPosInt.x, texPosInt.y); 52 Debug.Log(color); 53 } 54}

とはいえ、OnClickRawImage上のクリックイベントを引き金に実行しているのでしたらどちらの方式でも大差ないかもしれませんね。

投稿2019/11/05 11:51

Bongo

総合スコア10811

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

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

hokusou7500

2019/11/06 05:59

詳しい回答をいただきありがとうございます。教えていただいたコードを用いてやってみたところうまくいきました!!フォローさせていただきましたので、今後またお世話になることがあるかもしれませんがよろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問