提交 088a6597 编写于 作者: A Andrey Kamaev

Merged the trunk 8855,8885,8886

上级 3a40f276
......@@ -292,9 +292,9 @@ public:
typedef typename Distance::ValueType ValueType;
typedef typename Distance::ResultType DistanceType;
CV_DescriptorExtractorTest( const string _name, DistanceType _maxDist, const Ptr<DescriptorExtractor>& _dextractor, float _prevTime,
CV_DescriptorExtractorTest( const string _name, DistanceType _maxDist, const Ptr<DescriptorExtractor>& _dextractor,
Distance d = Distance() ):
name(_name), maxDist(_maxDist), prevTime(_prevTime), dextractor(_dextractor), distance(d) {}
name(_name), maxDist(_maxDist), dextractor(_dextractor), distance(d) {}
protected:
virtual void createDescriptorExtractor() {}
......@@ -400,7 +400,7 @@ protected:
double t = (double)getTickCount();
dextractor->compute( img, keypoints, calcDescriptors );
t = getTickCount() - t;
ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms (previous time = %g ms).\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows, prevTime );
ts->printf(cvtest::TS::LOG, "\nAverage time of computing one descriptor = %g ms.\n", t/((double)cvGetTickFrequency()*1000.)/calcDescriptors.rows);
if( calcDescriptors.rows != (int)keypoints.size() )
{
......@@ -485,7 +485,6 @@ protected:
string name;
const DistanceType maxDist;
const float prevTime;
Ptr<DescriptorExtractor> dextractor;
Distance distance;
......@@ -1027,11 +1026,15 @@ TEST( Features2d_Detector_PyramidFAST, regression )
test.safe_run();
}
/*
* Descriptors
*/
TEST( Features2d_DescriptorExtractor_ORB, regression )
{
// TODO adjust the parameters below
CV_DescriptorExtractorTest<Hamming> test( "descriptor-orb", (CV_DescriptorExtractorTest<Hamming>::DistanceType)12.f,
DescriptorExtractor::create("ORB"), 0.010f );
DescriptorExtractor::create("ORB") );
test.safe_run();
}
......@@ -1039,14 +1042,21 @@ TEST( Features2d_DescriptorExtractor_FREAK, regression )
{
// TODO adjust the parameters below
CV_DescriptorExtractorTest<Hamming> test( "descriptor-freak", (CV_DescriptorExtractorTest<Hamming>::DistanceType)12.f,
DescriptorExtractor::create("FREAK"), 0.010f );
DescriptorExtractor::create("FREAK") );
test.safe_run();
}
TEST( Features2d_DescriptorExtractor_BRIEF, regression )
{
CV_DescriptorExtractorTest<Hamming> test( "descriptor-brief", 1,
DescriptorExtractor::create("BRIEF"), 0.00527548f );
DescriptorExtractor::create("BRIEF") );
test.safe_run();
}
TEST( Features2d_DescriptorExtractor_OpponentBRIEF, regression )
{
CV_DescriptorExtractorTest<Hamming> test( "descriptor-opponent-brief", 1,
DescriptorExtractor::create("OpponentBRIEF") );
test.safe_run();
}
......
......@@ -1007,7 +1007,11 @@ enum
COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2,
COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2,
COLOR_COLORCVT_MAX = 125
// alpha premultiplication
COLOR_RGBA2mRGBA = 125,
COLOR_mRGBA2RGBA = 126,
COLOR_COLORCVT_MAX = 127
};
......
......@@ -306,7 +306,11 @@ enum
CV_YUV2GRAY_YUYV = CV_YUV2GRAY_YUY2,
CV_YUV2GRAY_YUNV = CV_YUV2GRAY_YUY2,
CV_COLORCVT_MAX = 125
// alpha premultiplication
CV_RGBA2mRGBA = 125,
CV_mRGBA2RGBA = 126,
CV_COLORCVT_MAX = 127
};
......
......@@ -3128,6 +3128,57 @@ inline void cvtYUV422toRGBA(Mat& _dst, int _stride, const uchar* _yuv)
converter(BlockedRange(0, _dst.rows));
}
/////////////////////////// RGBA <-> mRGBA (alpha premultiplied) //////////////
template<typename _Tp>
struct RGBA2mRGBA
{
typedef _Tp channel_type;
void operator()(const _Tp* src, _Tp* dst, int n) const
{
_Tp max_val = ColorChannel<_Tp>::max();
_Tp half_val = ColorChannel<_Tp>::half();
for( int i = 0; i < n; i++ )
{
_Tp v0 = *src++;
_Tp v1 = *src++;
_Tp v2 = *src++;
_Tp v3 = *src++;
*dst++ = (v0 * v3 + half_val) / max_val;
*dst++ = (v1 * v3 + half_val) / max_val;
*dst++ = (v2 * v3 + half_val) / max_val;
*dst++ = v3;
}
}
};
template<typename _Tp>
struct mRGBA2RGBA
{
typedef _Tp channel_type;
void operator()(const _Tp* src, _Tp* dst, int n) const
{
_Tp max_val = ColorChannel<_Tp>::max();
for( int i = 0; i < n; i++ )
{
_Tp v0 = *src++;
_Tp v1 = *src++;
_Tp v2 = *src++;
_Tp v3 = *src++;
_Tp v3_half = v3 / 2;
*dst++ = (v3==0)? 0 : (v0 * max_val + v3_half) / v3;
*dst++ = (v3==0)? 0 : (v1 * max_val + v3_half) / v3;
*dst++ = (v3==0)? 0 : (v2 * max_val + v3_half) / v3;
*dst++ = v3;
}
}
};
}//namespace cv
//////////////////////////////////////////////////////////////////////////////////////////
......@@ -3640,6 +3691,38 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
extractChannel(_src, _dst, code == CV_YUV2GRAY_UYVY ? 1 : 0);
}
break;
case CV_RGBA2mRGBA:
{
if (dcn <= 0) dcn = 4;
CV_Assert( scn == 4 && dcn == 4 );
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
{
CvtColorLoop(src, dst, RGBA2mRGBA<uchar>());
} else {
CV_Error( CV_StsBadArg, "Unsupported image depth" );
}
}
break;
case CV_mRGBA2RGBA:
{
if (dcn <= 0) dcn = 4;
CV_Assert( scn == 4 && dcn == 4 );
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
{
CvtColorLoop(src, dst, mRGBA2RGBA<uchar>());
} else {
CV_Error( CV_StsBadArg, "Unsupported image depth" );
}
}
break;
default:
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
}
......
......@@ -400,12 +400,13 @@ public class OpenCVTestCase extends TestCase {
Mat diff = new Mat();
Core.absdiff(expected, actual, diff);
double maxDiff = Core.norm(diff, Core.NORM_INF);
if (isEqualityMeasured)
assertTrue("Max difference between expected and actiual Mats is bigger than " + eps,
assertTrue("Max difference between expected and actiual Mats is "+ maxDiff + ", that bigger than " + eps,
Core.checkRange(diff, true, 0.0, eps));
else
assertFalse("Max difference between expected and actiual Mats is less than " + eps,
assertFalse("Max difference between expected and actiual Mats is "+ maxDiff + ", that less than " + eps,
Core.checkRange(diff, true, 0.0, eps));
}
......
......@@ -130,4 +130,43 @@ public class UtilsTest extends OpenCVTestCase {
}
public void testAlphaPremultiplication() {
final int size = 256;
Bitmap bmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Mat mOrig = new Mat(size, size, CvType.CV_8UC4);
Mat mUnPre = new Mat(size, size, CvType.CV_8UC4);
for(int y=0; y<size; y++) {
int a = y;
for(int x=0; x<size; x++) {
int color = Color.argb(a, 0, x, y);
bmp.setPixel(x, y, color);
mOrig.put(y, x, Color.red(color), Color.green(color), Color.blue(color), Color.alpha(color));
int colorUnPre = bmp.getPixel(x, y);
mUnPre.put(y, x, Color.red(colorUnPre), Color.green(colorUnPre), Color.blue(colorUnPre), Color.alpha(colorUnPre));
}
}
// Bitmap -> Mat
Mat m1 = new Mat();
Mat m2 = new Mat();
Utils.bitmapToMat(bmp, m1, false);
Imgproc.cvtColor(mOrig, m2, Imgproc.COLOR_RGBA2mRGBA);
assertMatEqual(m1, m2, 1.1);
Utils.bitmapToMat(bmp, m1, true);
assertMatEqual(m1, mUnPre, 1.1);
// Mat -> Bitmap
Bitmap bmp1 = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mOrig, bmp1, true);
Utils.bitmapToMat(bmp1, m1, true);
//assertMatEqual(m1, mUnPre, 1.1);
Mat diff = new Mat();
Core.absdiff(m1, mUnPre, diff);
int numDiff = Core.countNonZero(diff.reshape(1));
assertTrue(numDiff < size * 4);
}
}
......@@ -21,14 +21,14 @@ extern "C" {
/*
* Class: org_opencv_android_Utils
* Method: void nBitmapToMat(Bitmap b, long m_addr)
* Method: void nBitmapToMat2(Bitmap b, long m_addr, boolean unPremultiplyAlpha)
*/
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat
(JNIEnv * env, jclass, jobject bitmap, jlong m_addr);
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat2
(JNIEnv * env, jclass, jobject bitmap, jlong m_addr, jboolean needUnPremultiplyAlpha);
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat
(JNIEnv * env, jclass, jobject bitmap, jlong m_addr)
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat2
(JNIEnv * env, jclass, jobject bitmap, jlong m_addr, jboolean needUnPremultiplyAlpha)
{
AndroidBitmapInfo info;
void* pixels = 0;
......@@ -46,7 +46,8 @@ JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat
{
LOGD("nBitmapToMat: RGBA_8888 -> CV_8UC4");
Mat tmp(info.height, info.width, CV_8UC4, pixels);
tmp.copyTo(dst);
if(needUnPremultiplyAlpha) cvtColor(tmp, dst, COLOR_mRGBA2RGBA);
else tmp.copyTo(dst);
} else {
// info.format == ANDROID_BITMAP_FORMAT_RGB_565
LOGD("nBitmapToMat: RGB_565 -> CV_8UC4");
......@@ -71,56 +72,68 @@ JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat
}
}
// old signature is left for binary compatibility with 2.4.0 & 2.4.1, to removed in 2.5
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat
(JNIEnv * env, jclass, jobject bitmap, jlong m_addr);
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nBitmapToMat
(JNIEnv * env, jclass, jobject bitmap, jlong m_addr)
{
Java_org_opencv_android_Utils_nBitmapToMat2(env, 0, bitmap, m_addr, false);
}
/*
* Class: org_opencv_android_Utils
* Method: void nMatToBitmap(long m_addr, Bitmap b)
* Method: void nMatToBitmap2(long m_addr, Bitmap b, boolean premultiplyAlpha)
*/
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap
(JNIEnv * env, jclass, jlong m_addr, jobject bitmap);
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap
(JNIEnv * env, jclass, jlong m_addr, jobject bitmap)
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap2
(JNIEnv * env, jclass, jlong m_addr, jobject bitmap, jboolean needPremultiplyAlpha);
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap2
(JNIEnv * env, jclass, jlong m_addr, jobject bitmap, jboolean needPremultiplyAlpha)
{
AndroidBitmapInfo info;
void* pixels = 0;
Mat& dst = *((Mat*)m_addr);
Mat& src = *((Mat*)m_addr);
try {
LOGD("nMatToBitmap");
CV_Assert( AndroidBitmap_getInfo(env, bitmap, &info) >= 0 );
CV_Assert( info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
info.format == ANDROID_BITMAP_FORMAT_RGB_565 );
CV_Assert( dst.dims == 2 && info.height == (uint32_t)dst.rows && info.width == (uint32_t)dst.cols );
CV_Assert( dst.type() == CV_8UC1 || dst.type() == CV_8UC3 || dst.type() == CV_8UC4 );
CV_Assert( src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols );
CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4 );
CV_Assert( AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 );
CV_Assert( pixels );
if( info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 )
{
Mat tmp(info.height, info.width, CV_8UC4, pixels);
if(dst.type() == CV_8UC1)
if(src.type() == CV_8UC1)
{
LOGD("nMatToBitmap: CV_8UC1 -> RGBA_8888");
cvtColor(dst, tmp, CV_GRAY2RGBA);
} else if(dst.type() == CV_8UC3){
cvtColor(src, tmp, CV_GRAY2RGBA);
} else if(src.type() == CV_8UC3){
LOGD("nMatToBitmap: CV_8UC3 -> RGBA_8888");
cvtColor(dst, tmp, CV_RGB2RGBA);
} else if(dst.type() == CV_8UC4){
cvtColor(src, tmp, CV_RGB2RGBA);
} else if(src.type() == CV_8UC4){
LOGD("nMatToBitmap: CV_8UC4 -> RGBA_8888");
dst.copyTo(tmp);
if(needPremultiplyAlpha) cvtColor(src, tmp, COLOR_RGBA2mRGBA);
else src.copyTo(tmp);
}
} else {
// info.format == ANDROID_BITMAP_FORMAT_RGB_565
Mat tmp(info.height, info.width, CV_8UC2, pixels);
if(dst.type() == CV_8UC1)
if(src.type() == CV_8UC1)
{
LOGD("nMatToBitmap: CV_8UC1 -> RGB_565");
cvtColor(dst, tmp, CV_GRAY2BGR565);
} else if(dst.type() == CV_8UC3){
cvtColor(src, tmp, CV_GRAY2BGR565);
} else if(src.type() == CV_8UC3){
LOGD("nMatToBitmap: CV_8UC3 -> RGB_565");
cvtColor(dst, tmp, CV_RGB2BGR565);
} else if(dst.type() == CV_8UC4){
cvtColor(src, tmp, CV_RGB2BGR565);
} else if(src.type() == CV_8UC4){
LOGD("nMatToBitmap: CV_8UC4 -> RGB_565");
cvtColor(dst, tmp, CV_RGBA2BGR565);
cvtColor(src, tmp, CV_RGBA2BGR565);
}
}
AndroidBitmap_unlockPixels(env, bitmap);
......@@ -141,4 +154,14 @@ JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap
}
}
// old signature is left for binary compatibility with 2.4.0 & 2.4.1, to removed in 2.5
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap
(JNIEnv * env, jclass, jlong m_addr, jobject bitmap);
JNIEXPORT void JNICALL Java_org_opencv_android_Utils_nMatToBitmap
(JNIEnv * env, jclass, jlong m_addr, jobject bitmap)
{
Java_org_opencv_android_Utils_nMatToBitmap2(env, 0, m_addr, bitmap, false);
}
} // extern "C"
......@@ -81,19 +81,28 @@ public class Utils {
* <br>The output Mat is always created of the same size as the input Bitmap and of the 'CV_8UC4' type,
* it keeps the image in RGBA format.
* <br>The function throws an exception if the conversion fails.
*
* @param b is a valid input Bitmap object of the type 'ARGB_8888' or 'RGB_565'.
* @param m is a valid output Mat object, it will be reallocated if needed, so it's possible to pass an empty Mat.
* @param bmp is a valid input Bitmap object of the type 'ARGB_8888' or 'RGB_565'.
* @param mat is a valid output Mat object, it will be reallocated if needed, so it's possible to pass an empty Mat.
* @param unPremultiplyAlpha is a flag if the bitmap needs to be converted from alpha premultiplied format (like Android keeps 'ARGB_8888' ones) to regular one. The flag is ignored for 'RGB_565' bitmaps.
*/
public static void bitmapToMat(Bitmap b, Mat m) {
if (b == null)
throw new java.lang.IllegalArgumentException("Bitmap b == null");
if (m == null)
throw new java.lang.IllegalArgumentException("Mat m == null");
nBitmapToMat(b, m.nativeObj);
public static void bitmapToMat(Bitmap bmp, Mat mat, boolean unPremultiplyAlpha) {
if (bmp == null)
throw new java.lang.IllegalArgumentException("bmp == null");
if (mat == null)
throw new java.lang.IllegalArgumentException("mat == null");
nBitmapToMat2(bmp, mat.nativeObj, unPremultiplyAlpha);
}
/**
* Shortened form of the bitmapToMat(bmp, mat, unPremultiplyAlpha=false)
* @param bmp is a valid input Bitmap object of the type 'ARGB_8888' or 'RGB_565'.
* @param mat is a valid output Mat object, it will be reallocated if needed, so it's possible to pass an empty Mat.
*/
public static void bitmapToMat(Bitmap bmp, Mat mat) {
bitmapToMat(bmp, mat, false);
}
/**
* Converts OpenCV Mat to Android Bitmap.
* <p>
......@@ -102,18 +111,34 @@ public class Utils {
* <br>The output Bitmap object has to be of the same size as the input Mat and of the types 'ARGB_8888' or 'RGB_565'.
* <br>The function throws an exception if the conversion fails.
*
* @param m is a valid input Mat object of the types 'CV_8UC1', 'CV_8UC3' or 'CV_8UC4'.
* @param b is a valid Bitmap object of the same size as the Mat m and of type 'ARGB_8888' or 'RGB_565'.
* @param mat is a valid input Mat object of the types 'CV_8UC1', 'CV_8UC3' or 'CV_8UC4'.
* @param bmp is a valid Bitmap object of the same size as the Mat m and of type 'ARGB_8888' or 'RGB_565'.
* @param premultiplyAlpha is a flag if the Mat needs to be converted to alpha premultiplied format (like Android keeps 'ARGB_8888' bitmaps). The flag is ignored for 'RGB_565' bitmaps.
*/
public static void matToBitmap(Mat m, Bitmap b) {
if (m == null)
throw new java.lang.IllegalArgumentException("Mat m == null");
if (b == null)
throw new java.lang.IllegalArgumentException("Bitmap b == null");
nMatToBitmap(m.nativeObj, b);
public static void matToBitmap(Mat mat, Bitmap bmp, boolean premultiplyAlpha) {
if (mat == null)
throw new java.lang.IllegalArgumentException("mat == null");
if (bmp == null)
throw new java.lang.IllegalArgumentException("bmp == null");
nMatToBitmap2(mat.nativeObj, bmp, premultiplyAlpha);
}
/**
* Shortened form of the <b>matToBitmap(mat, bmp, premultiplyAlpha=false)</b>
* @param mat is a valid input Mat object of the types 'CV_8UC1', 'CV_8UC3' or 'CV_8UC4'.
* @param bmp is a valid Bitmap object of the same size as the Mat m and of type 'ARGB_8888' or 'RGB_565'.
*/
public static void matToBitmap(Mat mat, Bitmap bmp) {
matToBitmap(mat, bmp, false);
}
// native stuff
static {
System.loadLibrary("opencv_java");
}
private static native void nBitmapToMat(Bitmap b, long m_addr);
private static native void nBitmapToMat2(Bitmap b, long m_addr, boolean unPremultiplyAlpha);
private static native void nMatToBitmap(long m_addr, Bitmap b);
private static native void nMatToBitmap2(long m_addr, Bitmap b, boolean premultiplyAlpha);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册