does the jpegEncoder not clear the buffer?

Hi,

My question is: I want to crop the face from the source image. The source image may have many faces. you can see source.jpg.And I use jpegEncoder to encode face image and save to file.The code is

for(int i = 0; i < fcp.faceParams.size(); i++) {
        Rect faceBox;
        calcFaceBox(fcp.image, fcp.faceParams[i].detectBox, faceBox);

        string outFilePath = "allface/imageId:" + std::to_string(fcp.frameID)
                             + "num:" + std::to_string(count++) + ".jpg";
        ofstream *outFile = new ofstream(outFilePath.c_str());

        if(outFile) {
            //jpegencSrc->setCompressRate(100);
            //crop face
            jpegencSrc->setCropRect(faceBox.x, faceBox.y, faceBox.width, faceBox.height);
            unsigned long size = faceBox.width * faceBox.height * 3 / 2;
            unsigned char *buffer = new unsigned char;
            //if compress complete, the outbufsize will change smaller
            int ret = jpegencSrc->encodeFromFd(fdSrc, JCS_YCbCr, &buffer, size);
            if(ret == -1) {
                printf("save all face to file, jpeg encode failed.\n");
            }
            outFile->write((char *)buffer, size);
            outFile->close();
            delete outFile;
            delete buffer;
        }
}

But the buffer in jpegencoder may not clear, lead to the next face image was cover by previous face image. you can see the question.jpg.



question.jpg

question.jpg

Hi,

the face boxes size are different.

Thanks

Hi ClancyLain,

/**
     *
     * Encodes a JPEG image from a file descriptor (FD) of hardware
     * buffer memory.
     *
     * The application may allocate the memory for storing the JPEG
     * image. If the allocation is less than what is required, @c
     * libjpeg allocates more memory. The @a out_buf pointer and @a
     * out_buf_size are updated accordingly.
     *
     * Supports YUV420 and NV12 formats.
     *
     * @attention The application must free the @a out_buf memory.
     *
     * @param[out] fd Indicates the file descriptor (FD) of the hardware buffer.
     * @param[out] color_space Indicates the color_space to use for encoding.
     * @param[in] out_buf Specifies a pointer to the memory for the JPEG image.
     * @param[in] out_buf_size Specifies the size of the output buffer in bytes.
     * @return 0 for success, -1 otherwise.
     */
    int encodeFromFd(int fd, J_COLOR_SPACE color_space,
                     unsigned char **out_buf, unsigned long &out_buf_size);

Do you mean out_buf_size does not return correct encoded JPG size? The encoded JPG size depends on the YUV content and is not same for all frames.

Hi,

I don’t mean out_buf_size does not return correct encoded JPG size.The size is correct. But the buffer data may include previous face data,so you can see the next face data may coverd by previous face data. You can see the question.png. Only some of picture size is covered by previous face image. Because every frame has many face, and the frame rate is 25fps, so every second I have encoded and save many face image. I think the previous buffer may not clear data, and reuse to the next, so it will happen this phenomenon.

You also can do test: get a video and do face detection. and crop face boxes and enconde them to file by using setCropRect(faceBox.x, faceBox.y, faceBox.width, faceBox.height) and encodeFromFd.

Hi ClancyLian,
we have a sample tegra_multimedia_api\samples\09_camera_jpeg_capture to do continuous JPEG encoding on same NvBuffer and it works fine.

The source is Argus and looks different from yours. For further check, we may need your test code to reproduce the issue first.

Hi.

Because the sample tegra_multimedia_api\samples\09_camera_jpeg_capture setCropRect() function is all the same, it is (0,0,1920,1080), but now every time , I change the crop, the width and height may bigger or smaller. you also can read an image to test like this :

for(int i = 0; i < 100; i++) {
        int x = rand() % 500;
        int y = rand() % 500;
        int width = rand() % 100 + 100;
        int height = rand() % 100 + 100;
        <b>jpegenc->setCropRect(x, y, width, height);</b>

        unsigned long out_buf_size = width * height * 3 / 2;
        unsigned char *out_buf = new unsigned char[out_buf_size];
        <b>int ret = jpegenc->encodeFromFd( fd, JCS_YCbCr, &out_buf, out_buf_size);</b>

        std::string out_file_path = std::to_string(i) + ".jpg";
        std::ofstream * out_file = new ofstream(out_file_path);
        out_file->write((char *) out_buf, out_buf_size);
        out_file->close();
        delete out_file;
        delete[] out_buf;
    }

And observe the generate image.You can see in the attachment, for example, you can see the 52.jpg to 60.jpg, in the 54.jpg, it was coverd by 53.jpg. it is abnormal.!!!
seriesImage.tar.gz (2.01 MB)

Hi ClancyLian,

Please do alignment:

x += (x % 2);
y += (y % 2);
width += (width % 2);
height += (height % 2);
printf("x %d y %d w %d h %d \n", x,y,width,height);

We have try it and works!

Hi,

Thanks you reply. I have tried it, and it can work now. And should x, y width, height all align ?

Thanks.

In general, width and height always need to be even. x and y may not be required, but it is always better to be even-aligned.

Hi
I want to use jpegenc->encodeFromFd so what kind of library (.h file) to use the operation?