Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing framesize while capturing images in RGB565 and converting them to BMP leads to corrupt images #697

Open
3 tasks done
cnadler86 opened this issue Oct 25, 2024 · 3 comments

Comments

@cnadler86
Copy link
Contributor

cnadler86 commented Oct 25, 2024

Checklist

  • Checked the issue tracker for similar issues to ensure this is not a duplicate
  • Read the documentation to confirm the issue is not addressed there and your configuration is set correctly
  • Tested with the latest version to ensure the issue hasn't been fixed

How often does this bug occurs?

always

Expected behavior

I expect the image converted to be correct.

Actual behavior (suspected bug)

Some lines of the image are right, but some others don't.

Error logs or terminal output

No response

Steps to reproduce the behavior

Here is my code (its a micropython wrapper library):

Capture image:

mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format) {
if (!self->initialized) {
        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to capture image: Camera not initialized"));
    }
    if (self->captured_buffer) {
        esp_camera_fb_return(self->captured_buffer);
        self->captured_buffer = NULL;
    }
    
    static size_t out_len = 0;
    static uint8_t *out_buf = NULL;
    if (out_len>0 || out_buf) {
        free(out_buf);
        out_len = 0;
        out_buf = NULL;
    }

    ESP_LOGI(TAG, "Capturing image");
    self->captured_buffer = esp_camera_fb_get();
    if (!self->captured_buffer) {
        ESP_LOGE(TAG, "Failed to capture image");
        return mp_const_none;
    }
    
    if (out_format >= 0 && (mp_camera_pixformat_t)out_format != self->camera_config.pixel_format) {
        switch (out_format) {
            case PIXFORMAT_JPEG:
                if (frame2jpg(self->captured_buffer, self->camera_config.jpeg_quality, &out_buf, &out_len)) {
                    esp_camera_fb_return(self->captured_buffer);
                    mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf);
                    return result;
                } else {
                    return mp_const_none;
                }

            case PIXFORMAT_RGB888:
                out_len = self->captured_buffer->width * self->captured_buffer->height * 3;
                out_buf = (uint8_t *)malloc(out_len);
                if (!out_buf) {
                    ESP_LOGE(TAG, "out_buf malloc failed");
                    return mp_const_none;
                }
                if (fmt2rgb888(self->captured_buffer->buf, self->captured_buffer->len, self->captured_buffer->format, out_buf)) {
                    esp_camera_fb_return(self->captured_buffer);
                    mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf);
                    return result;
                } else {
                    return mp_const_none;
                }

            default:
                ESP_LOGI(TAG, "Returning image as bitmap");
                if (frame2bmp(self->captured_buffer, &out_buf, &out_len)) {
                    esp_camera_fb_return(self->captured_buffer);
                    mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf);
                    return result;
                } else {
                    return mp_const_none;
                }
        }
    }

    if (self->camera_config.pixel_format == PIXFORMAT_JPEG) {
        ESP_LOGI(TAG, "Captured image in JPEG format");
        return mp_obj_new_memoryview('b', self->captured_buffer->len, self->captured_buffer->buf);
    } else {
        ESP_LOGI(TAG, "Returning image as bitmap");
        if (frame2bmp(self->captured_buffer, &out_buf, &out_len)) {
            esp_camera_fb_return(self->captured_buffer);
            mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf);
            return result;
        } else {
            return mp_const_none;
        }
    }
}

Change Framesize:

void mp_camera_hal_set_frame_size(mp_camera_obj_t * self, framesize_t value) {
    if (!self->initialized) {
        mp_raise_ValueError(MP_ERROR_TEXT("Camera not initialized"));
    }
    sensor_t *sensor = esp_camera_sensor_get();
    if (!sensor->set_framesize) {
        mp_raise_ValueError(MP_ERROR_TEXT("No attribute frame_size"));
    }
    if (sensor->set_framesize(sensor, value) < 0) {
        mp_raise_ValueError(MP_ERROR_TEXT("Invalid setting for frame_size"));
    } else {
        self->camera_config.frame_size = value;
    }
}

Project release version

latest

System architecture

Intel/AMD 64-bit (modern PC, older Mac)

Operating system

Linux

Operating system version

ubuntu 2204 on WSL

Shell

Bash

Additional context

No response

@cnadler86
Copy link
Contributor Author

cnadler86 commented Oct 25, 2024

This doesn't happen when converting from jpeg.
Also, if I return to the initial frame size, the image is once again correct.

Here one screenshot (changed from QQVGA to QVGA):
image

Copy link

This issue appears to be stale. Please close it if its no longer valid.

@cnadler86
Copy link
Contributor Author

This is still an issue. A minor one, but an issue is an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant