Reputation: 3048
I have managed to capture a RAW image on Android and save it to disk as a DNG. What I want to do is read the raw sensor data of each "pixel" for the image. Specifically, I just want to read the green sensor values before any processing. What is the best way to do this?
Upvotes: 1
Views: 311
Reputation: 1
Here is a method I use. I average the green pixels, but this may not be the best strategy. Either way, here is how you get them.
fun getBayerFilter(cameraId: Int) {
val cameraCharacteristics: CameraCharacteristics = CameraInterface.cameraManager.getCameraCharacteristics(cameraId)
val bayerFilter = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT)
return bayerFilter
}
fun extractGreenPixels(image: Image, blackLevel: Float, cameraId: Int): FloatArray {
if (image.format != ImageFormat.RAW_SENSOR) {
throw IllegalArgumentException("Unsupported image format (Need to change this method to continue): ${image.format}")
}
// Get the Bayer filter.
val bayerFilter = getBayerFilter(cameraId)
val supportedFilters = listOf(
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR
)
if (bayerFilter !in supportedFilters) {
throw IllegalArgumentException("Unsupported Bayer filter (Need to change this method to continue): $bayerFilter")
}
// TODO: Why does "image.planes" have a warning? Format(0x20) is RAW_SENSOR
val planes = image.planes // This line has the warning: Could not find component description for Format(0x20) FourCC value(0x20363152)???
val buffer: ByteBuffer = planes[0].buffer
val rowStride: Int = planes[0].rowStride
val pixelStride: Int = planes[0].pixelStride
val width = image.width
val height = image.height
// Correct array size: width * height / 2
val greenPixels = FloatArray(width * height / 4)
var index = 0
for (y in 0 until height step 2) {
for (x in 0 until width step 2) {
val green1: Float
val green2: Float
when (bayerFilter) {
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB -> {
green1 = get16BitPixel(buffer, rowStride, pixelStride, x + 1, y)
green2 = get16BitPixel(buffer, rowStride, pixelStride, x, y + 1)
}
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG -> {
green1 = get16BitPixel(buffer, rowStride, pixelStride, x, y)
green2 = get16BitPixel(buffer, rowStride, pixelStride, x + 1, y + 1)
}
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG -> {
green1 = get16BitPixel(buffer, rowStride, pixelStride, x, y)
green2 = get16BitPixel(buffer, rowStride, pixelStride, x + 1, y + 1)
}
CameraMetadata.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR -> {
green1 = get16BitPixel(buffer, rowStride, pixelStride, x + 1, y)
green2 = get16BitPixel(buffer, rowStride, pixelStride, x, y + 1)
}
else -> throw IllegalArgumentException("Unsupported Bayer filter (Need to change this method to continue): $bayerFilter")
}
// Calculate the average green value
greenPixels[index++] = (green1 + green2) / 2.0f - blackLevel
}
}
return greenPixels
}
Upvotes: 0