CameraITS: Added tool for converting YUV420 NV21 and planar to JPEG
Change-Id: Ib0f9622164e635e08dca28b6d7e64154bf87b5a1
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py
index 4769bb7..89e579f 100644
--- a/apps/CameraITS/pymodules/its/image.py
+++ b/apps/CameraITS/pymodules/its/image.py
@@ -71,7 +71,7 @@
y = cap["data"][0:w*h]
u = cap["data"][w*h:w*h*5/4]
v = cap["data"][w*h*5/4:w*h*6/4]
- return convert_yuv420_to_rgb_image(y, u, v, w, h)
+ return convert_yuv420_planar_to_rgb_image(y, u, v, w, h)
elif cap["format"] == "jpeg":
return decompress_jpeg_to_rgb_image(cap["data"])
elif cap["format"] == "raw":
@@ -371,10 +371,10 @@
img = numpy.dot(img.reshape(w*h,3), ccm.T).reshape(h,w,3).clip(0.0,1.0)
return img
-def convert_yuv420_to_rgb_image(y_plane, u_plane, v_plane,
- w, h,
- ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
- yuv_off=DEFAULT_YUV_OFFSETS):
+def convert_yuv420_planar_to_rgb_image(y_plane, u_plane, v_plane,
+ w, h,
+ ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
+ yuv_off=DEFAULT_YUV_OFFSETS):
"""Convert a YUV420 8-bit planar image to an RGB image.
Args:
@@ -426,14 +426,20 @@
def load_yuv420_to_rgb_image(yuv_fname,
w, h,
+ layout="planar",
ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
yuv_off=DEFAULT_YUV_OFFSETS):
"""Load a YUV420 image file, and return as an RGB image.
+ Supported layouts include "planar" and "nv21". The "yuv" formatted captures
+ returned from the device via do_capture are in the "planar" layout; other
+ layouts may only be needed for loading files from other sources.
+
Args:
yuv_fname: The path of the YUV420 file.
w: The width of the image.
h: The height of the image.
+ layout: (Optional) the layout of the YUV data (as a string).
ccm_yuv_to_rgb: (Optional) the 3x3 CCM to convert from YUV to RGB.
yuv_off: (Optional) offsets to subtract from each of Y,U,V values.
@@ -441,13 +447,24 @@
RGB float-3 image array, with pixel values in [0.0, 1.0].
"""
with open(yuv_fname, "rb") as f:
- y = numpy.fromfile(f, numpy.uint8, w*h, "")
- v = numpy.fromfile(f, numpy.uint8, w*h/4, "")
- u = numpy.fromfile(f, numpy.uint8, w*h/4, "")
- return convert_yuv420_to_rgb_image(y,u,v,w,h,ccm_yuv_to_rgb,yuv_off)
+ if layout == "planar":
+ # Plane of Y, plane of V, plane of U.
+ y = numpy.fromfile(f, numpy.uint8, w*h, "")
+ v = numpy.fromfile(f, numpy.uint8, w*h/4, "")
+ u = numpy.fromfile(f, numpy.uint8, w*h/4, "")
+ elif layout == "nv21":
+ # Plane of Y, plane of interleaved VUVUVU...
+ y = numpy.fromfile(f, numpy.uint8, w*h, "")
+ vu = numpy.fromfile(f, numpy.uint8, w*h/2, "")
+ v = vu[0::2]
+ u = vu[1::2]
+ else:
+ raise its.error.Error('Unsupported image layout')
+ return convert_yuv420_planar_to_rgb_image(
+ y,u,v,w,h,ccm_yuv_to_rgb,yuv_off)
-def load_yuv420_to_yuv_planes(yuv_fname, w, h):
- """Load a YUV420 image file, and return separate Y, U, and V plane images.
+def load_yuv420_planar_to_yuv_planes(yuv_fname, w, h):
+ """Load a YUV420 planar image file, and return Y, U, and V plane images.
Args:
yuv_fname: The path of the YUV420 file.
diff --git a/apps/CameraITS/tools/convert_yuv_to_jpg.py b/apps/CameraITS/tools/convert_yuv_to_jpg.py
new file mode 100644
index 0000000..4498c2a
--- /dev/null
+++ b/apps/CameraITS/tools/convert_yuv_to_jpg.py
@@ -0,0 +1,37 @@
+# Copyright 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import its.image
+import sys
+
+def main():
+ """Open a YUV420 file and save it as a JPEG.
+
+ Command line args:
+ filename.yuv: The YUV420 file to open.
+ w: The width of the image.
+ h: The height of the image.
+ layout: The layout of the data, in ["planar", "nv21"].
+ """
+ if len(sys.argv) != 5:
+ print "Usage: python %s <filename.yuv> <w> <h> <layout>"%(sys.argv[0])
+ else:
+ fname, w,h = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])
+ layout = sys.argv[4]
+ img = its.image.load_yuv420_to_rgb_image(fname, w,h, layout=layout)
+ its.image.write_image(img, fname.replace(".yuv",".jpg"), False)
+
+if __name__ == '__main__':
+ main()
+