Neodroid  0.2.0
Machine Learning Environment Prototyping Tool
CameraSensor.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
7 using UnityEngine;
8 using UnityEngine.Experimental.Rendering;
9 
10 namespace droid.Runtime.Prototyping.Sensors.Camera.Deprecated {
13  enum ImageFormat {
16  Jpg_,
17 
20  Png_,
21 
24  Exr_,
25 
28  Tga_,
29 
32  Raw_
33  }
34 
38  [AddComponentMenu(SensorComponentMenuPath._ComponentMenuPath + "Camera" + SensorComponentMenuPath._Postfix)]
39  [ExecuteInEditMode]
40  [DisallowMultipleComponent]
41  [RequireComponent(typeof(UnityEngine.Camera))]
42  public class CameraSensor : Sensor,
46  [Header("Specific", order = 102)]
47  [SerializeField]
48  protected UnityEngine.Camera _Camera;
49 
52  protected bool _Grab = true;
53 
56  [SerializeField]
57  ImageFormat imageFormat = ImageFormat.Png_;
58 
61  [SerializeField]
62  [Range(0, 100)]
63  int jpegQuality = 75;
64 
67  protected IManager _Manager = null;
68 
69  public override String PrototypingTypeName { get { return ""; } }
70 
73  Texture2D _texture = null;
74 
75  [SerializeField] bool disable_encoding = false;
76 
80  [field : Header("Observation", order = 103)]
81  public byte[] Bytes { get; private set; } = { };
82 
83  public GraphicsFormat DataType {
84  get {
85  return GraphicsFormat.None; //this.imageFormat;
86  }
87  }
88 
89  public int[] Shape {
90  get {
91  var channels = 4;
92  if (this.imageFormat == ImageFormat.Jpg_) {
93  channels = 3;
94  }
95 
96  return new[] {this._texture.width, this._texture.height, channels};
97  }
98  }
99 
100  public string ArrayEncoding {
101  get {
102  switch (this.imageFormat) {
103  case ImageFormat.Jpg_:
104  return "JPEG";
105  case ImageFormat.Png_:
106  return "PNG";
107  case ImageFormat.Exr_:
108  return "EXR";
109  case ImageFormat.Tga_:
110  return "TGA";
111  case ImageFormat.Raw_:
112  return "RAW";
113  default: throw new ArgumentOutOfRangeException();
114  }
115  }
116  }
117 
121  protected override void PreSetup() {
122  if (this._Manager == null) {
123  this._Manager = FindObjectOfType<AbstractNeodroidManager>();
124  }
125 
126  if (this._Camera == null) {
127  this._Camera = this.GetComponent<UnityEngine.Camera>();
128  }
129 
130  if (this._Camera) {
131  var target_texture = this._Camera.targetTexture;
132  if (!target_texture) {
133  Debug.LogWarning($"No targetTexture defaulting to a texture of size ({NeodroidConstants._Default_Width}, {NeodroidConstants._Default_Height})");
134 
135  this._texture = new Texture2D(NeodroidConstants._Default_Width, NeodroidConstants._Default_Height);
136  } else {
137  var texture_format_str = target_texture.format.ToString();
138  if (Enum.TryParse(texture_format_str, out TextureFormat texture_format)) {
139  this._texture = new Texture2D(target_texture.width,
140  target_texture.height,
141  texture_format,
142  target_texture.useMipMap,
143  !target_texture.sRGB);
144  } else {
145  #if NEODROID_DEBUG
146  Debug.LogWarning($"Texture format {texture_format_str} is not a valid TextureFormat for Texture2D for observer {this.Identifier}");
147  #endif
148  }
149  }
150  }
151  #if NEODROID_DEBUG
152  if (this._Manager?.SimulatorConfiguration != null) {
153  if (this._Manager.SimulatorConfiguration.SimulationType != SimulationType.Frame_dependent_
154  && Application.isEditor) {
155  //Debug.Log("Notice that camera observations may be out of sync with other observation data, because simulation configuration is not frame dependent");
156  }
157  }
158  #endif
159  }
160 
163  protected virtual void OnPostRender() { this.UpdateBytes(); }
164 
168  protected void UpdateBytes() {
169  if (!this._Grab) {
170  return;
171  }
172 
173  this._Grab = false;
174 
175  if (this._Camera) {
176  var current_render_texture = RenderTexture.active;
177  RenderTexture.active = this._Camera.targetTexture;
178 
179  if (this._texture) {
180  this._texture.ReadPixels(new Rect(0, 0, this._texture.width, this._texture.height), 0, 0);
181  this._texture.Apply();
182  } else {
183  #if NEODROID_DEBUG
184  Debug.LogWarning("Texture not available!");
185  #endif
186  var target_texture = this._Camera.targetTexture;
187  this._texture = new Texture2D(target_texture.width,
188  target_texture.height,
189  NeodroidConstants._Default_TextureFormat,
190  false);
191  }
192 
193  if (!this.disable_encoding) {
194  switch (this.imageFormat) {
195  case ImageFormat.Jpg_:
196  this.Bytes = this._texture.EncodeToJPG(this.jpegQuality);
197  break;
198  case ImageFormat.Png_:
199  this.Bytes = this._texture.EncodeToPNG();
200  break;
201  case ImageFormat.Exr_:
202  this.Bytes = this._texture.EncodeToEXR();
203  break;
204  case ImageFormat.Tga_:
205  this.Bytes = this._texture.EncodeToTGA();
206  break;
207  case ImageFormat.Raw_:
208  this.Bytes = this._texture.GetRawTextureData();
209  break;
210  /*case ImageFormat.Ppm_:
211  // create a file header for ppm formatted file
212  string headerStr = string.Format("P6\n{0} {1}\n255\n", rect.width, rect.height);
213  fileHeader = System.Text.Encoding.ASCII.GetBytes(headerStr);
214  this.Bytes = _texture.GetRawTextureData();
215 
216  new System.Threading.Thread(() =>
217  {
218  // create file and write optional header with image bytes
219  var f = System.IO.File.Create(filename);
220  if (fileHeader != null) f.Write(fileHeader, 0, fileHeader.Length);
221  f.Write(fileData, 0, fileData.Length);
222  f.Close();
223  Debug.Log(string.Format("Wrote screenshot {0} of size {1}", filename, fileData.Length));
224  }).Start();
225  */
226  default: throw new ArgumentOutOfRangeException();
227  }
228  }
229 
230  RenderTexture.active = current_render_texture;
231  } else {
232  Debug.LogWarning($"No camera found on {this}");
233  }
234  }
235 
239  public override IEnumerable<float> FloatEnumerable { get { return null; } }
240 
244  public override void UpdateObservation() {
245  this._Grab = true;
246  if (this._Manager?.SimulatorConfiguration?.SimulationType != SimulationType.Frame_dependent_) {
247  if (Application.isPlaying) {
248  this._Camera.Render();
249  }
250 
251  this.UpdateBytes();
252  }
253  }
254 
259  public override string ToString() { return $"Rendered {this.imageFormat} image"; }
260  }
261 }
ISimulatorConfiguration SimulatorConfiguration
Definition: IManager.cs:8
SimulationType
Determines the discrete timesteps of the simulation environment.