CameraITS: Update rawStats computation to only use active array region.
Change-Id: Idf70268e134d22f5c3e2407022f52b51e662a450
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 3b378cc..2a6b98c 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -577,7 +577,10 @@
channel is computed, and the do_capture call returns two 4-element float
images of dimensions (rawWidth / gridWidth, rawHeight / gridHeight),
concatenated back-to-back, where the first iamge contains the 4-channel
- means and the second contains the 4-channel variances.
+ means and the second contains the 4-channel variances. Note that only
+ pixels in the active array crop region are used; pixels outside this
+ region (for example optical black rows) are cropped out before the
+ gridding and statistics computation is performed.
For the rawStats format, if the gridWidth is not provided then the raw
image width is used as the default, and similarly for gridHeight. With
diff --git a/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
index 16dff85..b7c96e2 100644
--- a/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
+++ b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
@@ -27,32 +27,40 @@
#include <string.h>
jfloatArray com_android_cts_verifier_camera_its_computeStatsImage(JNIEnv* env, jobject thiz,
- jbyteArray img, jint width, jint height, jint gridWidth, jint gridHeight)
+ // The full pixel array read off the sensor.
+ jbyteArray img,
+ jint width, jint height,
+ // The active array crop region.
+ jint aax, jint aay, jint aaw, jint aah,
+ // The size of each grid cell to use when computing stats from the active array.
+ jint gridWidth, jint gridHeight)
{
int bufSize = (int)(env->GetArrayLength(img));
unsigned char *buf = (unsigned char*)env->GetByteArrayElements(img, /*is_copy*/NULL);
- // Size of the raw image.
- const int w = width;
- const int h = height;
+ // Size of the full raw image pixel array.
+ const int paw = width;
+ const int pah = height;
// Size of each grid cell.
const int gw = gridWidth;
const int gh = gridHeight;
// Number of grid cells (rounding down to full cells only at right+bottom edges).
- const int ngx = w / gw;
- const int ngy = h / gh;
+ const int ngx = aaw / gw;
+ const int ngy = aah / gh;
float *mean = new float[ngy*ngx*4];
float *var = new float[ngy*ngx*4];
+ // For each grid cell ...
for (int gy = 0; gy < ngy; gy++) {
for (int gx = 0; gx < ngx; gx++) {
float sum[4] = {0};
float sumSq[4] = {0};
int count[4] = {0};
- for (int y = gy*gh; y < (gy+1)*gh; y++) {
+ // Iterate over pixels in the grid cell
+ for (int y = aay+gy*gh; y < aay+(gy+1)*gh; y++) {
int chnOffset = (y & 0x1) * 2;
- unsigned char *pbuf = buf + 2*y*w + 2*gx*gw;
- for (int x = gx*gw; x < (gx+1)*gw; x++) {
+ unsigned char *pbuf = buf + 2*y*paw + 2*gx*gw + 2*aax;
+ for (int x = aax+gx*gw; x < aax+(gx+1)*gw; x++) {
// input is RAW16
int byte0 = *pbuf++;
int byte1 = *pbuf++;
@@ -81,7 +89,7 @@
}
static JNINativeMethod gMethods[] = {
- { "computeStatsImage", "([BIIII)[F",
+ { "computeStatsImage", "([BIIIIIIII)[F",
(void *) com_android_cts_verifier_camera_its_computeStatsImage },
};
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 706c374..49ce01c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -726,10 +726,13 @@
int format = readers[i].getImageFormat();
if (format == ImageFormat.RAW_SENSOR) {
if (mCaptureRawIsStats) {
+ int aaw = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics)
+ .width();
+ int aah = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics)
+ .height();
jsonSurface.put("format", "rawStats");
- jsonSurface.put("width", readers[i].getWidth()/mCaptureStatsGridWidth);
- jsonSurface.put("height",
- readers[i].getHeight()/mCaptureStatsGridHeight);
+ jsonSurface.put("width", aaw/mCaptureStatsGridWidth);
+ jsonSurface.put("height", aah/mCaptureStatsGridHeight);
} else if (mCaptureRawIsDng) {
jsonSurface.put("format", "dng");
} else {
@@ -1170,14 +1173,16 @@
if (height <= 0) {
height = ItsUtils.getMaxSize(sizes).getHeight();
}
- if (mCaptureStatsGridWidth <= 0) {
- mCaptureStatsGridWidth = width;
- }
- if (mCaptureStatsGridHeight <= 0) {
- mCaptureStatsGridHeight = height;
- }
- // TODO: Crop to the active array in the stats image analysis.
+ // The stats computation only applies to the active array region.
+ int aaw = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics).width();
+ int aah = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics).height();
+ if (mCaptureStatsGridWidth <= 0 || mCaptureStatsGridWidth > aaw) {
+ mCaptureStatsGridWidth = aaw;
+ }
+ if (mCaptureStatsGridHeight <= 0 || mCaptureStatsGridHeight > aah) {
+ mCaptureStatsGridHeight = aah;
+ }
outputSizes[i] = new Size(width, height);
}
@@ -1569,9 +1574,18 @@
long startTimeMs = SystemClock.elapsedRealtime();
int w = capture.getWidth();
int h = capture.getHeight();
+ int aaw = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics)
+ .width();
+ int aah = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics)
+ .height();
+ int aax = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics)
+ .left;
+ int aay = ItsUtils.getActiveArrayCropRegion(mCameraCharacteristics)
+ .top;
int gw = mCaptureStatsGridWidth;
int gh = mCaptureStatsGridHeight;
- float[] stats = StatsImage.computeStatsImage(img, w, h, gw, gh);
+ float[] stats = StatsImage.computeStatsImage(
+ img, w, h, aax, aay, aaw, aah, gw, gh);
long endTimeMs = SystemClock.elapsedRealtime();
Log.e(TAG, "Raw stats computation takes " + (endTimeMs - startTimeMs) + " ms");
int statsImgSize = stats.length * 4;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index 363c9e1..65e4970 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.graphics.ImageFormat;
+import android.graphics.Rect;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
@@ -123,6 +124,10 @@
return getMaxSize(getOutputSizes(ccs, format));
}
+ public static Rect getActiveArrayCropRegion(CameraCharacteristics ccs) {
+ return ccs.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+ }
+
private static Size[] getOutputSizes(CameraCharacteristics ccs, int format)
throws ItsException {
StreamConfigurationMap configMap = ccs.get(
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java
index 037177c..c354d62 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java
@@ -30,6 +30,7 @@
}
public native static float[] computeStatsImage(
- byte[] img, int width, int height, int gridW, int gridH);
+ byte[] img, int width, int height,
+ int aaX, int aaY, int aaW, int aaH, int gridW, int gridH);
}