Unable to Draw text using cvPutText()

781 views
Skip to first unread message

bwa

unread,
Oct 24, 2014, 5:13:45 AM10/24/14
to jav...@googlegroups.com
Hello, 

I am using JavaCV on Android and want to draw some Text onto my Frames while recording from Camera.
Recording works fine, but in the recorded video I don't see any Text.

Here is my the relevant code in onPreviewFrame() :

  public void onPreviewFrame(byte[] data, Camera camera) {
            if (yuvIplimage != null && recording) {
                yuvIplimage.getByteBuffer().put(data);
                cvPutText(yuvIplimage,"HELLO_JAVA_CV?",cvPoint(0,0),mCvFont, opencv_core.CvScalar.WHITE);
                // Log.d(TAG, "Writing Frame");
                try {
                    long t = 1000 * (System.currentTimeMillis() - startTime);
                    if (t > recorder.getTimestamp()) {
                        recorder.setTimestamp(t);
                    }
                    recorder.record(yuvIplimage);
                } catch (FFmpegFrameRecorder.Exception e) {
                    Log.d(TAG, e.getMessage());
                    e.printStackTrace();
                }
            }
            mCamera.addCallbackBuffer(data);
        }

There's no error, so I guess I am calling the cvPutText() function in a wrong way?
Does anyone see the problem?

Thanks



Mihael Francekovic

unread,
Oct 24, 2014, 5:43:12 AM10/24/14
to jav...@googlegroups.com
Did you initialize your mCvFont before calling cvPutText??

--

---
You received this message because you are subscribed to the Google Groups "javacv" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacv+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

bwa

unread,
Oct 24, 2014, 6:43:26 AM10/24/14
to jav...@googlegroups.com
Yep, I initialized mCvFont once using this code:

opencv_core.CvFont mCvFont = new opencv_core.CvFont();
cvInitFont(mCvFont,CV_FONT_HERSHEY_SCRIPT_SIMPLEX,1.0,1.0,0,1,CV_AA);

Mihael Francekovic

unread,
Oct 24, 2014, 6:45:22 AM10/24/14
to jav...@googlegroups.com
Maybe cvPoint(x,y) stands for low left corner of text.. so you are writing it but above the image..
Try cvPoint(imageWidth/2, imageHeight/2)

Mihael Francekovic

unread,
Oct 24, 2014, 7:45:30 AM10/24/14
to jav...@googlegroups.com
Did this solve your error? :)

Samuel Audet

unread,
Oct 26, 2014, 1:34:18 AM10/26/14
to jav...@googlegroups.com
On 10/24/2014 06:13 PM, bwa wrote:
> cvPutText(yuvIplimage,"HELLO_JAVA_CV?",cvPoint(0,0),mCvFont, opencv_core.CvScalar.WHITE);

Almost every OpenCV function does not support the YUV format. We first
need to convert those images to RGB/BGR...

Samuel

bwa

unread,
Oct 26, 2014, 4:08:20 PM10/26/14
to jav...@googlegroups.com
Did this solve your error? :)

unfortunately not.

Almost every OpenCV function does not support the YUV format. We first 
need to convert those images to RGB/BGR... 

Okay, I tried to extend the RecordActivity example with to write text into the video.
I am not sure how to convert YUV to RGB but I found a method that should do the trick:

    void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
        final 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 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
            }
        }
    }

so the onPreviewFrame calls this method before recording the frame:

int[] pixels = new int[previewSize.width * previewSize.height];
 
   @Override

        public void onPreviewFrame(byte[] data, Camera camera) {
            /* get video data */
            decodeYUV420SP(pixels, data, previewSize.width,  previewSize.height);

            if (yuvIplimage != null && recording) {
                yuvIplimage.getByteBuffer().put(data);
                Log.v(LOG_TAG,"Writing Frame");

                try {
                    long t = 1000 * (System.currentTimeMillis() - startTime);
                    if (t > recorder.getTimestamp()) {
                        recorder.setTimestamp(t);
                    }
                    cvPutText(yuvIplimage,"HELLO_JAVA_CV?",cvPoint(imageWidth/2,imageHeight/2),mFont, opencv_core.CvScalar.WHITE);
                    recorder.record(yuvIplimage);
                } catch (FFmpegFrameRecorder.Exception e) {
                    Log.v(LOG_TAG,e.getMessage());
                    e.printStackTrace();
                }
            }
        } 

But there's still no text in the recorded video...

Samuel Audet

unread,
Nov 3, 2014, 5:47:14 AM11/3/14
to jav...@googlegroups.com
On 10/27/2014 05:08 AM, bwa wrote:
> Okay, I tried to extend the RecordActivity
> <https://code.google.com/p/javacv/source/browse/samples/RecordActivity.java>example
> with to write text into the video.
> I am not sure how to convert YUV to RGB but I found a method that should
> do the trick:

Just use the functions from OpenCV. Something like this should work:

IplImage yuvimage = IplImage.create(width, height * 3 / 2,
IPL_DEPTH_8U, 1);
IplImage rgbimage = IplImage.create(width, height, IPL_DEPTH_8U, 3);
yuvimage.getByteBuffer().put(data);
cvCvtColor(yuvimage, rgbimage, CV_YUV2BGR_NV21);

Samuel
Message has been deleted

bwa

unread,
Nov 3, 2014, 10:02:45 AM11/3/14
to jav...@googlegroups.com
Thank you for your reply, Samuel.
It works now.

Could you please explain why I need to multiply the original height by 3/2?

Also, I noticed that when I manipulate the frames, the recorded video is lagging.
Any way to improve performance here?

Samuel Audet

unread,
Nov 15, 2014, 4:38:51 AM11/15/14
to jav...@googlegroups.com
On 11/04/2014 12:02 AM, bwa wrote:
> Thank you for your reply, Samuel.
> It works now.
>
> Could you please explain why I need to multiply the original height by 3/2?

Because that's how OpenCV wants it:
https://github.com/Itseez/opencv/blob/2.4/modules/imgproc/src/color.cpp#L4218

> Also, I noticed that when I manipulate the frames, the recorded video is lagging.
> Any way to improve performance here?

You could try the "ultrafast" preset by calling
`recorder.setVideoOption("preset", "ultrafast")` before calling
`recorder.start()`.

Samuel

Alex Pandy

unread,
Apr 8, 2015, 2:53:53 AM4/8/15
to jav...@googlegroups.com
But cvCvtColor(yuvimage, rgbimage, CV_YUV2BGR_NV21);
is not working for me... can anyone share that method
As text appears but the video is in grayscale

Samuel Audet

unread,
Apr 8, 2015, 9:59:01 AM4/8/15
to jav...@googlegroups.com
On 04/08/2015 03:53 PM, Alex Pandy wrote:
> But cvCvtColor(yuvimage, rgbimage, CV_YUV2BGR_NV21);
> is not working for me... can anyone share that method
> As text appears but the video is in grayscale

Try instead to use AndroidFrameConverter.convert(byte[],int,int):
http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/AndroidFrameConverter.html#convert-byte:A-int-int-
It's easier to use, but let us know if you have problems with it.

Samuel

Reply all
Reply to author
Forward
0 new messages