Skip to content

Commit

Permalink
lockPixels is showing weird behavior, pixel values diff in C++/Java
Browse files Browse the repository at this point in the history
I'll try to pass uchar array and height, width instead of bitmap and construct vpImage from array itself
  • Loading branch information
Unknown committed Mar 23, 2018
1 parent e1da652 commit da84c80
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 115 deletions.
56 changes: 0 additions & 56 deletions Proposal/proposal.md

This file was deleted.

2 changes: 1 addition & 1 deletion VispAndroidDemoApp/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

160 changes: 108 additions & 52 deletions VispAndroidDemoApp/app/src/main/cpp/native-lib.cpp
Expand Up @@ -3,37 +3,110 @@
#include <android/bitmap.h>

#include <visp3/core/vpImageTools.h>
#include <visp3/core/vpImageConvert.h>
#include <visp3/core/vpDisplay.h>
#include <visp3/detection/vpDetectorAprilTag.h>

#define LOG_TAG "** VISP **"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOG_TAG "VISP-NDK"
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

void printARGB(AndroidBitmapInfo *info, void *pixels);
void printGreyscale(const vpImage<u_char> &I);
std::string getBitmapFormat(const int &i);
void createGreyScale(vpImage<u_char> &I, void *pixels);
void detectTag(vpImage<u_char> &I);

extern "C" JNIEXPORT void JNICALL
Java_example_vispapriltag_MainActivity_processImage(JNIEnv *env, jclass type, jobject bitmap) {

AndroidBitmapInfo info;
void *pixels;
int ret;

if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOG("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
} else
LOG("Bitmap format: %s", getBitmapFormat(info.format).c_str());

if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOG("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return;
}

printARGB(&info, pixels);

vpImage<u_char> I;
// I.init((u_char*) pixels,info.height, info.width,false);

I.init(info.height, info.width);
createGreyScale(I, pixels);

// printGreyscale(I);

detectTag(I);
// pixels = I.bitmap;

AndroidBitmap_unlockPixels(env, bitmap);
}

void printARGB(AndroidBitmapInfo *info, void *pixels) {
// In Android 32 bits go from: 0,1,2....2130~,-2130~,...,-2,-1
// So for C++
// The only difference is in ARGB vs ABGR

static void transpose(AndroidBitmapInfo *info, void *pixels) {
for (int yy = 0; yy < info->height; yy++) {
uint16_t *line = (uint16_t *) pixels;
uint16_t *line_end = line + info->width;
uint32_t *line = (uint32_t *) pixels;
uint32_t *line_end = line + info->width;

int w = 0;
while (line < line_end) {
// Swapping
// *line = *line ^ *line_end;
// *line_end = *line ^ *line_end;
// *line = *line ^ *line_end;

// Getting R,G,B values
// ((*line & 0xF800) >> 11)<<3
// ((*line & 0x7E0) >> 5)<<2
// (*line & 0x1F)<<2
*line = (uint16_t) (((((*line & 0xF800) >> 11) << 3) + \
(((*line & 0x7E0) >> 5) << 2) + \
(*line & 0x1F) << 2) / 3);

LOG("Color value: %d. ABGR values at (%d,%d) may be: (%d,%d,%d,%d)", *line,yy, w, \
(*line >> 24) & 0xff, \
(*line >> 16) & 0xff, \
(*line >> 8) & 0xff, \
(*line) & 0xff);
++line;
// --line_end;
++w;
}
}
}

static void detectTag(vpImage<u_char> &I) {
std::string getBitmapFormat(const int &i) {
switch (i) {
case ANDROID_BITMAP_FORMAT_A_8:
return "A_8";
case ANDROID_BITMAP_FORMAT_RGBA_8888:
return "RGBA_8888";
case ANDROID_BITMAP_FORMAT_RGBA_4444:
return "RGBA_4444";
case ANDROID_BITMAP_FORMAT_RGB_565:
return "RGB_565";
case ANDROID_BITMAP_FORMAT_NONE:
return "None";

default:
return "Format not found";
}
}

void createGreyScale(vpImage<u_char> &I, void *pixels) {
for (uint yy = 0; yy < I.getHeight(); yy++) {
uint32_t *line = (uint32_t *) pixels;
uint32_t *line_end = line + I.getWidth();

uint w = 0;
while (line < line_end) {
I(yy, w, (const u_char &) (
(((*line >> 16) & 0xff) + ((*line >> 8) & 0xff) + ((*line) & 0xff)) / 3));
++line;
++w;
}
}
}

void detectTag(vpImage<u_char> &I) {
#ifdef VISP_HAVE_APRILTAG
vpDetectorAprilTag::vpAprilTagFamily tagFamily = vpDetectorAprilTag::TAG_36h11;
vpDetectorAprilTag::vpPoseEstimationMethod poseEstimationMethod = vpDetectorAprilTag::HOMOGRAPHY_VIRTUAL_VS;
Expand All @@ -44,9 +117,10 @@ static void detectTag(vpImage<u_char> &I) {
vpCameraParameters cam;
cam.initPersProjWithoutDistortion(615.1674805, 615.1675415, 312.1889954, 243.4373779);

std::cout << "cam:\n" << cam << std::endl;
std::cout << "poseEstimationMethod: " << poseEstimationMethod << std::endl;
std::cout << "tagFamily: " << tagFamily << std::endl;
std::stringstream ss;
ss << "cam:\n" << cam << std::endl;
ss << "poseEstimationMethod: " << poseEstimationMethod << std::endl;
ss << "tagFamily: " << tagFamily << std::endl;

try {
//! [Create AprilTag detector]
Expand All @@ -64,12 +138,13 @@ static void detectTag(vpImage<u_char> &I) {
//! [Detect and compute pose]
std::vector<vpHomogeneousMatrix> cMo_vec;
detector.detect(I, tagSize, cam, cMo_vec);
// detector.detect(I);
//! [Detect and compute pose]
t = vpTime::measureTimeMs() - t;

std::stringstream ss;
ss << "Detection time: " << t << " ms for " << detector.getNbObjects() << " tags";
vpDisplay::displayText(I, 40, 20, ss.str(), vpColor::red);
const std::string tmp = ss.str();
LOG("%s", tmp.c_str());

//! [Parse detected codes]
for (size_t i = 0; i < detector.getNbObjects(); i++) {
Expand All @@ -90,36 +165,17 @@ static void detectTag(vpImage<u_char> &I) {
// vpDisplay::displayText(I, p[j] + vpImagePoint(15, 5), number.str(), vpColor::blue);
// }
}
}catch (const vpException &e) {
std::cerr << "Catch an exception: " << e.getMessage() << std::endl;
} catch (const vpException &e) {
LOG("Catch an exception: %s", e.getMessage());
}
#endif
}

extern "C"
JNIEXPORT void JNICALL
Java_example_vispapriltag_MainActivity_processImage(JNIEnv *env, jclass type, jobject bitmap) {

AndroidBitmapInfo info;
void *pixels;
int ret;

if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}

if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return;
}

vpImage<uint16_t > I;
I.init(((uint16_t *) pixels), info.width, info.height, false);

detectTag(I);
// transpose(&info, pixels);

AndroidBitmap_unlockPixels(env, bitmap);
pixels = I.bitmap;
void printGreyscale(const vpImage<u_char> &I){
std::stringstream ss;
for(uint i = 0;i<I.getWidth();++i)
for(uint j = 0;j<I.getHeight();++j)
ss << "At ("<<i<<","<<j<<"): "<<(u_int) I(i,j)<<"\n";
const std::string tmp = ss.str();
LOG("%s", tmp.c_str());
}
Expand Up @@ -3,22 +3,28 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import static example.vispapriltag.Constants.*;

public class MainActivity extends AppCompatActivity {

public static final String TAG = "VISP";

// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("visp_core");
Expand All @@ -32,6 +38,8 @@ public class MainActivity extends AppCompatActivity {

ImageView imageView;

public static native void processImage(Bitmap bitmap);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -90,10 +98,10 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
*
* @param uri URI of the selected image
*/
private void saveImageCopy(Uri uri){
private void saveImageCopy(Uri uri) {

try{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),uri);
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);

int h1 = bitmap.getHeight();
int w1 = bitmap.getWidth();
Expand All @@ -105,14 +113,54 @@ private void saveImageCopy(Uri uri){
w1 = bitmap.getWidth();
}

// turn it to grayscale here only
// don't know why but there's some issue with locking of pixels
bitmap = toGrayscale(bitmap);

Log.d(TAG, bitmap.getConfig().toString());

for(int i=0;i<bitmap.getHeight();++i)
for(int j=0;j<bitmap.getWidth();++j) {
int color = bitmap.getPixel(i, j);
Log.d(TAG, color + "," + Color.alpha(color) + "," + Color.red(color)
+ "," + Color.green(color) + "," + Color.blue(color));
}

// do the image processing
processImage(bitmap);

// rescale it. Only for 16x16 or smaller debug images
if (bitmap.getWidth() < 30 || bitmap.getHeight() < 30)
bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() * 10, bitmap.getHeight() * 10, false);

imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}

public static native void processImage(Bitmap bitmap);
public Bitmap toGrayscale(Bitmap bmpOriginal){
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();

// Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
// for(int i=0;i<bmpOriginal.getWidth();++i)
// for(int j=0;j<bmpOriginal.getHeight();++j) {
// int color = bmpOriginal.getPixel(i, j);
// // TODO optimize this
// bmpGrayscale.setPixel(i,j,(Color.red(color) + Color.green(color) + Color.blue(color))/3);
// }

Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);

return bmpGrayscale;
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit da84c80

Please sign in to comment.