diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2012-12-17 11:56:30 -0800 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2012-12-17 12:03:53 -0800 |
commit | e2bade8aee27e29debfa711754dc7eca6275ec0b (patch) | |
tree | 6e82c86669ca23bba50c398c1e0867b12151b688 /jni/filters/kmeans.cc | |
parent | d89b654d50f714fdf32cb1a36c2c8860d0d6a933 (diff) | |
download | android_packages_apps_Snap-e2bade8aee27e29debfa711754dc7eca6275ec0b.tar.gz android_packages_apps_Snap-e2bade8aee27e29debfa711754dc7eca6275ec0b.tar.bz2 android_packages_apps_Snap-e2bade8aee27e29debfa711754dc7eca6275ec0b.zip |
Improved performance for Kmeans filter.
Bug: 7739334
Change-Id: I5ab1eb429d65f84449a61deca962a47f2b6dbc8b
Diffstat (limited to 'jni/filters/kmeans.cc')
-rw-r--r-- | jni/filters/kmeans.cc | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/jni/filters/kmeans.cc b/jni/filters/kmeans.cc index 599657c8e..97cead7bc 100644 --- a/jni/filters/kmeans.cc +++ b/jni/filters/kmeans.cc @@ -21,25 +21,59 @@ extern "C" { #endif -void JNIFUNCF(ImageFilterKMeans, nativeApplyFilter, jobject bitmap, jint width, jint height, jint p) +/* + * For reasonable speeds: + * k < 30 + * small_ds_bitmap width/height < 64 pixels. + * large_ds_bitmap width/height < 512 pixels + * + * bad for high-frequency image noise + */ + +void JNIFUNCF(ImageFilterKMeans, nativeApplyFilter, jobject bitmap, jint width, jint height, + jobject large_ds_bitmap, jint lwidth, jint lheight, jobject small_ds_bitmap, + jint swidth, jint sheight, jint p, jint seed) { char* destination = 0; + char* larger_ds_dst = 0; + char* smaller_ds_dst = 0; AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + AndroidBitmap_lockPixels(env, large_ds_bitmap, (void**) &larger_ds_dst); + AndroidBitmap_lockPixels(env, small_ds_bitmap, (void**) &smaller_ds_dst); unsigned char * dst = (unsigned char *) destination; - int len = width * height * 4; + unsigned char * small_ds = (unsigned char *) smaller_ds_dst; + unsigned char * large_ds = (unsigned char *) larger_ds_dst; + + // setting for small bitmap + int len = swidth * sheight * 4; int dimension = 3; int stride = 4; - int iterations = 4; + int iterations = 20; int k = p; + unsigned int s = seed; unsigned char finalCentroids[k * stride]; - // TODO: add downsampling and better heuristic to improve speed, then up iterations + // get initial picks from small downsampled image + runKMeans<unsigned char, int>(k, finalCentroids, small_ds, len, dimension, + stride, iterations, s); + + + len = lwidth * lheight * 4; + iterations = 8; + unsigned char nextCentroids[k * stride]; + + // run kmeans on large downsampled image + runKMeansWithPicks<unsigned char, int>(k, nextCentroids, large_ds, len, + dimension, stride, iterations, finalCentroids); + + len = width * height * 4; - // does K-Means clustering on rgb bitmap colors - runKMeans<unsigned char, int>(k, finalCentroids, dst, len, dimension, stride, iterations); - applyCentroids<unsigned char, int>(k, finalCentroids, dst, len, dimension, stride); + // apply to final image + applyCentroids<unsigned char, int>(k, nextCentroids, dst, len, dimension, stride); + AndroidBitmap_unlockPixels(env, small_ds_bitmap); + AndroidBitmap_unlockPixels(env, large_ds_bitmap); AndroidBitmap_unlockPixels(env, bitmap); } #ifdef __cplusplus |