Closed GoogleCodeExporter closed 8 years ago
That would be a request for enhancement, not a defect. However, it's pretty
easy to convert an IplImage to a Bitmap, so I'm not sure we need anything
special in JavaCV. Can you try the following?
We should be able to transfer data by simply calling
Bitmap.copyPixelsFromBuffer(IplImage.getByteBuffer());
but the pixel formats need to match, which seems to be 32-bit ARGB888 in the
case of Android, so an IplImage of IPL_DEPTH_8U with 4 channels should do the
trick.
Original comment by samuel.a...@gmail.com
on 12 May 2011 at 11:06
Really thank you, samuel. Thank you.
Original comment by indy0...@gmail.com
on 13 May 2011 at 12:53
Hi Guys!
I also have a problem with Bitmap <-> IplImage conversion.
When i run the code below and want to show the resulting Bitmap, I get an Image
with two times the picture of the original Image... it looks like the picture
is added another time on the right side of the original picture. Had any of you
the same problem?
Thanks a lot for any help!
try
{
IplImage image = IplImage.create(width, height, IPL_DEPTH_8U, 4);
//sourcImage is a Bitmap which comes from the sd-card of the emulator,
//from .jpg-file
sourceImage.copyPixelsToBuffer(image.getByteBuffer());
//smoothedImage is also a Bitmap created as follows
//Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
smoothedImage.copyPixelsFromBuffer(image.getByteBuffer());
}catch (Exception e)
{
//this is the line of code that sends a real error message to the log.
Log.e("ERROR", "ERROR in Code: " + e.toString());
e.printStackTrace();
}
Original comment by markus.f...@gmail.com
on 16 May 2011 at 7:35
sorry forgot some additional information.
I'm using JavaCV (javacv-bin-20110511) on Mac OS X 10.6.7 with eclipse and
android sdk.
OpenCV-2.2.0-android-arm and android-ndk-r4-crystax.
Original comment by markus.f...@gmail.com
on 16 May 2011 at 8:26
I found a solution... The problem was that the camera captured image was in
RGB_565 format and I had to convert it into ARGB_8888 via:
argbImage = rgb565Image.copy(Config.ARGB_8888, true);
thx anyway
Original comment by markus.f...@gmail.com
on 16 May 2011 at 4:13
[deleted comment]
Android Bitmap's format and IplImage's format matching is very important.
IplImage image = IplImage.create(width, height, IPL_DEPTH_8U, 4);
IplImage _3image = IplImage.create(width, height, IPL_DEPTH_8U, 3);
IplImage _1image = IplImage.create(width, height, IPL_DEPTH_8U, 1);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
1. iplimage -> bitmap
bitmap.copyPixelsFromBuffer(image.getByteBuffer());
2. bitmap -> iplimage
bitmap.copyPixelsToBuffer(image.getByteBuffer());
3. iplimage(4channel) -> iplimage(3channel or 1channel)
cvCvtColor(image, _3image, CV_BGRA2BGR);
cvCvtColor(_3image, _1image, CV_RGB2GRAY);
--------------------------------------------------------------------------------
---
Create iplimage from Android's camera byte[] data
private IplImage _4iplToBitmap;
_4iplToBitmap = IplImage.create(width, height, IPL_DEPTH_8U, 4);
int [] _temp = new int[width*height];
if(_4iplToBitmap!= null){
decodeYUV420SP(_temp, data, width, height);
_4iplToBitmap.getIntBuffer().put(_temp);
}
protected void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int
height) {
int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;
rgb[yp] = 0xff000000 | ((b << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((r >> 10) & 0xff);
}
}
}
Original comment by indy0...@gmail.com
on 17 May 2011 at 1:21
It's also possible to convert the RGB_565 format with OpenCV's cvCvtColor():
CV_BGR2BGR565 =12,
CV_RGB2BGR565 =13,
CV_BGR5652BGR =14,
CV_BGR5652RGB =15,
CV_BGRA2BGR565 =16,
CV_RGBA2BGR565 =17,
CV_BGR5652BGRA =18,
CV_BGR5652RGBA =19,
CV_GRAY2BGR565 =20,
CV_BGR5652GRAY =21,
There is nothing for planar YUV though.
Original comment by samuel.a...@gmail.com
on 17 May 2011 at 1:34
Hey,
getting the following image when trying your code:
http://imageshack.us/f/832/testkm.jpg/
Would need immediate help...
Thanks in advance!
Original comment by sebilin...@gmail.com
on 28 May 2011 at 7:50
Check the source in JavaCV's samples facepreview.java
I think use the SUBSAMPLING_FACTOR.
public static final int SUBSAMPLING_FACTOR = 4;
Original comment by indy0...@gmail.com
on 1 Jun 2011 at 1:12
Thanks so far!
I get a grayimage now, how to obtain the colors?
Original comment by sebilin...@gmail.com
on 1 Jun 2011 at 1:58
If you are trying to use images from a Camera object, simply copy the bytes
from the images as per the format that should be NV12
http://www.fourcc.org/yuv.php#NV12 into what OpenCV usually wants, that is RGB
24bpp http://www.fourcc.org/rgb.php#BI_RGB
Original comment by samuel.a...@gmail.com
on 1 Jun 2011 at 2:14
The format is NV21, which shouldn't matter that much...
Is there an existing algorithm for such conversion?
Original comment by sebilin...@gmail.com
on 1 Jun 2011 at 2:19
FFmpeg's swscale can do the conversion.. I'm sure there are pure Java functions
already made, but I haven't checked into it. FFmpeg would probably be more
efficient anyway.
Original comment by samuel.a...@gmail.com
on 2 Jun 2011 at 4:56
I managed to decode the YUV data to an IPLImage.
Now I converted the IPLImage color space to HSV via:
IplImage iplHSV = IplImage.create(width, height, IPL_DEPTH_8U, 3);
cvCvtColor(iplImage, iplHSV, CV_BGR2HSV);
If I try to save it back to a Bitmap via
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(iplHSV.getByteBuffer());
I get "java.lang.RuntimeException: Buffer not large enough for pixels"...
Any ideas?
Original comment by sebilin...@gmail.com
on 3 Jun 2011 at 5:40
Bitmap.Config.ARGB_8888 is 4 channel.
Channel is Alpha, Red, Green, Blue.
8888 is 1channel = 8bit => 8bit/8bit/8bit/8bit
8bit 4channel.
IplImage ipl2bitmap = IplImage.create(width, height, IPL_DEPTH_8U, 4);
Original comment by indy0...@gmail.com
on 3 Jun 2011 at 10:47
Thanks!
But the problem is, I can't convert it into HSV 4-channel IPLImage, as HSV only
has 3 of them:
06-06 16:30:59.585: ERROR/AndroidRuntime(6608): java.lang.RuntimeException:
Unknown exception.
06-06 16:30:59.585: ERROR/AndroidRuntime(6608): at
com.googlecode.javacv.cpp.opencv_imgproc.cvCvtColor(Native Method)
Original comment by sebilin...@gmail.com
on 6 Jun 2011 at 2:32
4channel -> 3channel -> HSV
cvCvtColor(4channel, 3channel, CV_BGRA2BGR);
cvCvtColor(3channel, hsv, CV_BGR2HSV);
Original comment by indy0...@gmail.com
on 7 Jun 2011 at 1:01
I have convert a bitmap to IplImage on a java file doing:
argbImage = bitmap.copy(Config.ARGB_8888, true);
IplImage image = IplImage.create(w, h, IPL_DEPTH_8U, 4);
IplImage _3image = IplImage.create(w, h, IPL_DEPTH_8U, 3);
argbImage.copyPixelsToBuffer(image.getByteBuffer());
cvCvtColor(image, _3image,CV_BGRA2BGR )
I passed this IplImage (_3image) as an argument of a native function.
Using JNI, I can't use this IplImage in my function Funct(JNIEnv * env, jobject
thiz, jobject img, jint w, jint h). The app is closed automaticaly when I try
to do some modifications on the image (cvSetReal3D) or when I want to extract
img Size using cvGetSize(img).
Any ideas?? thanks in advance.
Original comment by rafegasf...@gmail.com
on 17 Oct 2011 at 11:26
@rafegasf, I think you should look at JavaCPP to be able to define a native
function such as with
http://code.google.com/p/javacv/source/browse/trunk/javacv/src/com/googlecode/ja
vacv/cpp/cvkernels.java
Please post other questions you may have on the mailing list, thank you
Original comment by samuel.a...@gmail.com
on 19 Oct 2011 at 3:26
hi samuel,
thanks for your report. I think that i have defined my native function
correctly:
import com.google.javacv.cpp.opencv_core.IplImage;
public class NativeLib extends JavaMain() {
public native IplImage funcition (IplImage img, float[] vector1, int [] vector2);
static{
System.loadLibrary("demo");
}
}
but when I run on a terminal to create .h file needed by .cpp files:
javah -jni namePakage.NativeLibrary
i have an error:
javadoc: error - In doclet class com.sun.tools.javah.MainDoclet, method start
has thrown an exception java.lang. reflect.InvocationTargetException
com.sun.tools.javac.code.Symbol$CompletionFailuer: class file for
com.googlecode.javacv.cpp.opencv_core not found
which is my mistake?
the only thing that I need is Convert the android.graphics.bitmap image to
IplImage to do some opencv modifications in the nativeCode (JNI) and return the
new image to Java code.
I have try a lot of things and the app doesn't works yet...
if anybody knows how I can do it, please, help me!
Thank you in advance!
Original comment by rafegasf...@gmail.com
on 8 Nov 2011 at 4:09
@rafegasf, please refer to the documentation of JavaCPP for some details about
defining native functions, and please post your JavaCPP-related questions on
JavaCPP's mailing list, not here, thank you.
If you only wish to convert an Android Bitmap to IplImage, you do not need to
define a native function. Just copy the data, as demonstrated in some of the
comments above.
Original comment by samuel.a...@gmail.com
on 9 Nov 2011 at 8:24
[deleted comment]
If I want to use cvCanny, how can I convert the output to android Bitmap?
Original comment by booker0108@gmail.com
on 10 Feb 2012 at 8:03
Use cvConvertScale() to convert the resulting images back to 8-bit data first,
then copy the 8-bit data to a Bitmap.
Original comment by samuel.a...@gmail.com
on 11 Feb 2012 at 1:53
sorry,i have writen an example use this library as:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
imageView = (ImageView) findViewById(R.id.imageView1);
addButton = (Button) findViewById(R.id.buttonAdd);
iplImage = cvLoadImage(filename);
addButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
long start = System.currentTimeMillis();
if (iplImage != null) {
cvSmooth(iplImage, iplImage, CV_GAUSSIAN, 3);
bitmapDes.copyPixelsFromBuffer(iplImage.getByteBuffer());
cvSaveImage(filename, iplImage);
cvReleaseImage(iplImage);
}
imageView.setImageBitmap(bitmapDes);
Log.d("Time","time : "+ (System.currentTimeMillis() - start ));
}
});
}
and when i run it force close with log:
03-07 14:57:08.750: E/AndroidRuntime(16745): FATAL EXCEPTION: main
03-07 14:57:08.750: E/AndroidRuntime(16745): java.lang.RuntimeException:
/home/saudet/workspace/android/OpenCV-2.3.1/modules/imgproc/src/smooth.cpp:1547:
error: (-215) dst.size() == src.size() && (smooth_type == CV_BLUR_NO_SCALE ||
dst.type() == src.type()) in function void cvSmooth(const void*, void*, int,
int, int, double, double)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
com.googlecode.javacv.cpp.opencv_imgproc.cvSmooth(Native Method)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
com.googlecode.javacv.cpp.opencv_imgproc.cvSmooth(opencv_imgproc.java:626)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
com.example.bitmap.test.ImageFilterOpenCV$1.onClick(ImageFilterOpenCV.java:61)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
android.view.View.performClick(View.java:2574)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
android.view.View$PerformClick.run(View.java:9223)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
android.os.Handler.handleCallback(Handler.java:587)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
android.os.Handler.dispatchMessage(Handler.java:92)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
android.os.Looper.loop(Looper.java:130)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
android.app.ActivityThread.main(ActivityThread.java:3691)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
java.lang.reflect.Method.invokeNative(Native Method)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
java.lang.reflect.Method.invoke(Method.java:507)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
03-07 14:57:08.750: E/AndroidRuntime(16745): at
dalvik.system.NativeStart.main(Native Method)
03-07 14:57:13.359: I/dalvikvm(16745): threadid=4: reacting to signal 3
it run on Window 7?
please help me,and 1 more,i don't know how to convert between CvArr and
IplImage.
with cvSmooth() i use IplImage as CvArr , it accepted but with blur() it did
not accept ??
Thanks
Original comment by nguyenngochoang89
on 7 Mar 2012 at 8:09
hi,I want to know if there is anyone get the right-format Iplimage with the
method given at comment #7?Thank you!
Original comment by fujiaoji...@gmail.com
on 13 Mar 2012 at 7:22
Sorry #27 it wont work and you wont have the solution to do it... I'm still
waiting.
Original comment by alei...@gmail.com
on 22 Mar 2012 at 5:51
I cannot find cvLoadImage()
How can I solve it?
Original comment by booker0108@gmail.com
on 4 Apr 2012 at 10:03
I use this method to process a picture taken with a camera. I try to request
the NV21 picture format, if it is supported, to avoid unnecessary
compression/decompression. If it is not supported, I decode the JPEG as follows:
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Size size = camera.getParameters().getPictureSize();
CvMat rgbImage;
if (camera.getParameters().getPictureFormat() == ImageFormat.NV21) {
if (size.height % 2 != 0)
throw new RuntimeException("Odd height not supported");
CvMat nv21Image = CvMat.create(size.height + (size.height/2), size.width, CV_8UC1);
rgbImage = CvMat.create(size.height, size.width, CV_8UC3);
nv21Image.getByteBuffer().put(data);
cvCvtColor(nv21Image, rgbImage, CV_YUV2BGR_NV21);
nv21Image.release();
} else {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bitmap.getConfig() == Bitmap.Config.RGB_565) {
CvMat rgb565Image = CvMat.create(size.height, size.width, CV_8UC2);
bitmap.copyPixelsToBuffer(rgb565Image.getByteBuffer());
rgbImage = CvMat.create(size.height, size.width, CV_8UC3);
cvCvtColor(rgb565Image, rgbImage, CV_BGR5652BGR);
rgb565Image.release();
}
else if (bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
rgbImage = CvMat.create(size.height, size.width, CV_8UC4);
bitmap.copyPixelsToBuffer(rgbImage.getByteBuffer());
}
else
throw new RuntimeException("Unsupported bitmap config: " + bitmap.getConfig());
bitmap.recycle();
}
// ... continue using rgbImage
}
Original comment by viliam.d...@gmail.com
on 14 May 2013 at 8:11
Thanks @indy0 for #16 !!
Original comment by iriarte....@gmail.com
on 11 Jun 2014 at 6:22
It took a while, but I've finally managed to figure out a nice to way to go
about this:
http://bytedeco.org/news/2015/04/04/javacv-frame-converters/
So, JavaCV 0.11 now comes with `AndroidFrameConverter` and
`OpenCVFrameConverter` to implement this functionality:
http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/AndroidFrameConverter.htm
l
http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/OpenCVFrameConverter.html
Enjoy!
Original comment by samuel.a...@gmail.com
on 11 Apr 2015 at 2:07
Original issue reported on code.google.com by
indy0...@gmail.com
on 12 May 2011 at 8:38Attachments: