mirror of
https://github.com/opencv/opencv.git
synced 2024-11-30 06:10:02 +08:00
Fix Android NDK camera's color format conversions
This commit is contained in:
parent
125b9f6057
commit
b9b65e9392
@ -31,6 +31,13 @@ using namespace cv;
|
|||||||
#define COLOR_FormatYUV420Planar 19
|
#define COLOR_FormatYUV420Planar 19
|
||||||
#define COLOR_FormatYUV420SemiPlanar 21
|
#define COLOR_FormatYUV420SemiPlanar 21
|
||||||
|
|
||||||
|
#define FOURCC_BGR CV_FOURCC_MACRO('B','G','R','3')
|
||||||
|
#define FOURCC_RGB CV_FOURCC_MACRO('R','G','B','3')
|
||||||
|
#define FOURCC_GRAY CV_FOURCC_MACRO('G','R','E','Y')
|
||||||
|
#define FOURCC_NV21 CV_FOURCC_MACRO('N','V','2','1')
|
||||||
|
#define FOURCC_YV12 CV_FOURCC_MACRO('Y','V','1','2')
|
||||||
|
#define FOURCC_UNKNOWN 0xFFFFFFFF
|
||||||
|
|
||||||
template <typename T> class RangeValue {
|
template <typename T> class RangeValue {
|
||||||
public:
|
public:
|
||||||
T min, max;
|
T min, max;
|
||||||
@ -180,7 +187,7 @@ class AndroidCameraCapture : public IVideoCapture
|
|||||||
bool sessionOutputAdded = false;
|
bool sessionOutputAdded = false;
|
||||||
bool targetAdded = false;
|
bool targetAdded = false;
|
||||||
// properties
|
// properties
|
||||||
bool convertToRgb = false;
|
uint32_t fourCC = FOURCC_UNKNOWN;
|
||||||
bool settingWidth = false;
|
bool settingWidth = false;
|
||||||
bool settingHeight = false;
|
bool settingHeight = false;
|
||||||
int desiredWidth = 640;
|
int desiredWidth = 640;
|
||||||
@ -303,10 +310,17 @@ public:
|
|||||||
|
|
||||||
if ( (uvPixelStride == 2) && (vPixel == uPixel + 1) && (yLen == frameWidth * frameHeight) && (uLen == ((yLen / 2) - 1)) && (vLen == uLen) ) {
|
if ( (uvPixelStride == 2) && (vPixel == uPixel + 1) && (yLen == frameWidth * frameHeight) && (uLen == ((yLen / 2) - 1)) && (vLen == uLen) ) {
|
||||||
colorFormat = COLOR_FormatYUV420SemiPlanar;
|
colorFormat = COLOR_FormatYUV420SemiPlanar;
|
||||||
|
if (fourCC == FOURCC_UNKNOWN) {
|
||||||
|
fourCC = FOURCC_NV21;
|
||||||
|
}
|
||||||
} else if ( (uvPixelStride == 1) && (vPixel = uPixel + uLen) && (yLen == frameWidth * frameHeight) && (uLen == yLen / 4) && (vLen == uLen) ) {
|
} else if ( (uvPixelStride == 1) && (vPixel = uPixel + uLen) && (yLen == frameWidth * frameHeight) && (uLen == yLen / 4) && (vLen == uLen) ) {
|
||||||
colorFormat = COLOR_FormatYUV420Planar;
|
colorFormat = COLOR_FormatYUV420Planar;
|
||||||
|
if (fourCC == FOURCC_UNKNOWN) {
|
||||||
|
fourCC = FOURCC_YV12;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
colorFormat = COLOR_FormatUnknown;
|
colorFormat = COLOR_FormatUnknown;
|
||||||
|
fourCC = FOURCC_UNKNOWN;
|
||||||
LOGE("Unsupported format");
|
LOGE("Unsupported format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -324,9 +338,41 @@ public:
|
|||||||
}
|
}
|
||||||
Mat yuv(frameHeight + frameHeight/2, frameWidth, CV_8UC1, buffer.data());
|
Mat yuv(frameHeight + frameHeight/2, frameWidth, CV_8UC1, buffer.data());
|
||||||
if (colorFormat == COLOR_FormatYUV420Planar) {
|
if (colorFormat == COLOR_FormatYUV420Planar) {
|
||||||
cv::cvtColor(yuv, out, convertToRgb ? cv::COLOR_YUV2RGB_YV12 : cv::COLOR_YUV2BGR_YV12);
|
switch (fourCC) {
|
||||||
|
case FOURCC_BGR:
|
||||||
|
cv::cvtColor(yuv, out, cv::COLOR_YUV2BGR_YV12);
|
||||||
|
break;
|
||||||
|
case FOURCC_RGB:
|
||||||
|
cv::cvtColor(yuv, out, cv::COLOR_YUV2RGB_YV12);
|
||||||
|
break;
|
||||||
|
case FOURCC_GRAY:
|
||||||
|
cv::cvtColor(yuv, out, cv::COLOR_YUV2GRAY_YV12);
|
||||||
|
break;
|
||||||
|
case FOURCC_YV12:
|
||||||
|
yuv.copyTo(out);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGE("Unexpected FOURCC value: %d", fourCC);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if (colorFormat == COLOR_FormatYUV420SemiPlanar) {
|
} else if (colorFormat == COLOR_FormatYUV420SemiPlanar) {
|
||||||
cv::cvtColor(yuv, out, convertToRgb ? COLOR_YUV2RGB_NV21 : cv::COLOR_YUV2BGR_NV21);
|
switch (fourCC) {
|
||||||
|
case FOURCC_BGR:
|
||||||
|
cv::cvtColor(yuv, out, cv::COLOR_YUV2BGR_NV21);
|
||||||
|
break;
|
||||||
|
case FOURCC_RGB:
|
||||||
|
cv::cvtColor(yuv, out, cv::COLOR_YUV2RGB_NV21);
|
||||||
|
break;
|
||||||
|
case FOURCC_GRAY:
|
||||||
|
cv::cvtColor(yuv, out, cv::COLOR_YUV2GRAY_NV21);
|
||||||
|
break;
|
||||||
|
case FOURCC_NV21:
|
||||||
|
yuv.copyTo(out);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGE("Unexpected FOURCC value: %d", fourCC);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGE("Unsupported video format: %d", colorFormat);
|
LOGE("Unsupported video format: %d", colorFormat);
|
||||||
return false;
|
return false;
|
||||||
@ -341,14 +387,14 @@ public:
|
|||||||
return isOpened() ? frameWidth : desiredWidth;
|
return isOpened() ? frameWidth : desiredWidth;
|
||||||
case CV_CAP_PROP_FRAME_HEIGHT:
|
case CV_CAP_PROP_FRAME_HEIGHT:
|
||||||
return isOpened() ? frameHeight : desiredHeight;
|
return isOpened() ? frameHeight : desiredHeight;
|
||||||
case CV_CAP_PROP_CONVERT_RGB:
|
|
||||||
return convertToRgb ? 1 : 0;
|
|
||||||
case CAP_PROP_AUTO_EXPOSURE:
|
case CAP_PROP_AUTO_EXPOSURE:
|
||||||
return autoExposure ? 1 : 0;
|
return autoExposure ? 1 : 0;
|
||||||
case CV_CAP_PROP_EXPOSURE:
|
case CV_CAP_PROP_EXPOSURE:
|
||||||
return exposureTime;
|
return exposureTime;
|
||||||
case CV_CAP_PROP_ISO_SPEED:
|
case CV_CAP_PROP_ISO_SPEED:
|
||||||
return sensitivity;
|
return sensitivity;
|
||||||
|
case CV_CAP_PROP_FOURCC:
|
||||||
|
return fourCC;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -377,9 +423,40 @@ public:
|
|||||||
settingHeight = false;
|
settingHeight = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case CV_CAP_PROP_CONVERT_RGB:
|
case CV_CAP_PROP_FOURCC:
|
||||||
convertToRgb = (value != 0);
|
{
|
||||||
|
uint32_t newFourCC = cvRound(value);
|
||||||
|
if (fourCC == newFourCC) {
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
switch (newFourCC) {
|
||||||
|
case FOURCC_BGR:
|
||||||
|
case FOURCC_RGB:
|
||||||
|
case FOURCC_GRAY:
|
||||||
|
fourCC = newFourCC;
|
||||||
|
return true;
|
||||||
|
case FOURCC_YV12:
|
||||||
|
if (colorFormat == COLOR_FormatYUV420Planar) {
|
||||||
|
fourCC = newFourCC;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOGE("Unsupported FOURCC conversion COLOR_FormatYUV420SemiPlanar -> COLOR_FormatYUV420Planar");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case FOURCC_NV21:
|
||||||
|
if (colorFormat == COLOR_FormatYUV420SemiPlanar) {
|
||||||
|
fourCC = newFourCC;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOGE("Unsupported FOURCC conversion COLOR_FormatYUV420Planar -> COLOR_FormatYUV420SemiPlanar");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOGE("Unsupported FOURCC value: %d\n", fourCC);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
case CAP_PROP_AUTO_EXPOSURE:
|
case CAP_PROP_AUTO_EXPOSURE:
|
||||||
autoExposure = (value != 0);
|
autoExposure = (value != 0);
|
||||||
if (isOpened()) {
|
if (isOpened()) {
|
||||||
@ -394,14 +471,14 @@ public:
|
|||||||
camera_status_t status = ACaptureRequest_setEntry_i64(captureRequest.get(), ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime);
|
camera_status_t status = ACaptureRequest_setEntry_i64(captureRequest.get(), ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime);
|
||||||
return status == ACAMERA_OK;
|
return status == ACAMERA_OK;
|
||||||
}
|
}
|
||||||
break;
|
return false;
|
||||||
case CV_CAP_PROP_ISO_SPEED:
|
case CV_CAP_PROP_ISO_SPEED:
|
||||||
if (isOpened() && sensitivityRange.Supported()) {
|
if (isOpened() && sensitivityRange.Supported()) {
|
||||||
sensitivity = (int32_t)value;
|
sensitivity = (int32_t)value;
|
||||||
camera_status_t status = ACaptureRequest_setEntry_i32(captureRequest.get(), ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity);
|
camera_status_t status = ACaptureRequest_setEntry_i32(captureRequest.get(), ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity);
|
||||||
return status == ACAMERA_OK;
|
return status == ACAMERA_OK;
|
||||||
}
|
}
|
||||||
break;
|
return false;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user