espressif / esp32-camera

Apache License 2.0
1.93k stars 642 forks source link

Odd colors from SC101IOT #688

Closed dehne closed 2 weeks ago

dehne commented 1 month ago

Checklist

Issue or Suggestion Description

I've been trying (unsuccessfully) to get the SC101IOT to take a useful photo using an ESP32S3 with PSRAM with ESP32-Cam. The basic "take picture example" works flawlessly, returning a frame buffer of the correct size (1843200 = 1280 720 2). That leads me to believe I've got much of the basics set up correctly.

I then modified the example to convert the contents of the frame buffer to a jpeg and store it on an SD card. This, too, works without error. But the captured photo is very strange. The scene is recognizable, but both the colors and the brightness are completely wrong. Here's an example. It's an image of the ceiling in my lab. The ceiling is made of white-painted boards with grooves between them:

Photo of ceiling taken in YUV422 mode

Since getting this result, I've done quite a bit of investigation into what might be happening. For example, with the help of the datasheet for the SC101AP sensor module that's used in the SC101IOT, I added support for raw Bayer RGB mode to eliminate the whole RGB to YUV to RGB transform series. When I put the sensor in RAW mode, the pixel data in the frame buffer is definitely Bayer RGB, but the images look essentially the same as in YUV422 mode. Here's a photo of my ceiling taken in RAW mode (in dimmer light), converted to jpeg and stored on an SD card:

Photo of ceiling taken in RAW mode

I've done a bunch of other tests, all of which point to the sensor actually sending odd data, but that seems really unlikely. I just can't figure out what I must be doing wrong. Has anyone seen similar behavior when using the SC101IOT?

jksemple commented 1 month ago

This may be another consequence of the bug reported in #676. If your camera is returning rgb565 the conversion to jpg assumes the 16bit pixel value is ordered as high byte low byte. Try swapping the byte order of your image and it should fix the problem.

dehne commented 1 month ago

Thanks for responding. Yes, I'm probably missing something like that!

But I'm pretty sure it's not an endian problem in this case because, according to the sensor datasheet, in the two PIXELFORMATs it supports -- YUV422 and RAW -- pixel components are all 8-bit values. In YUV422, they are laid out as YUYV order. In RAW format, the image is basically a straight dump of the image sensor with its Bayer filter. So, the even numbered lines are laid out G R G while the odd lines are B G B. Again, the components are only 8-bits long.

Again, thanks for taking the time to respond.

jksemple commented 1 month ago

You said your frame buffer is 1280 x 720 x 2 which implies you expect 2 bytes per pixel so I assumed you had converted to Rgb565.

dehne commented 1 month ago

Sorry for the confusion. Yes, like RGB565, YUV422 and (for this sensor, at least) RAW formats are 2 bytes per pixel. Though, unlike RGB565, the pixel components for these formats aren't contiguous.

dehne commented 1 month ago

Sorry for the confusion. Yes, like RGB565, YUV422 and (for this sensor, at least) RAW formats are 2 bytes per pixel. Though, unlike RGB565, the pixel components for these formats aren't contiguous.

dehne commented 1 month ago

I've done quite a bit more experimenting, but haven't resolved this issue.

I've validated that, when using the PIXFORMAT_RAW and the shade test pattern, the pixel values received in the frame buffer have 8-bit components and are laid out in the buffer in a Bayer pattern, as expected. That is, the even lines of the image are big-endian bgbgbg... and the odd lines are grgrgr... where each r, g, or b is an 8-bit value. I validated this by varying the RGB values the shade test pattern uses. (The shade test pattern produces an image of a solid user-specified color.) For example, if I change the r component value and hold the g and b components constant, the places in the frame buffer where the r component should be all change, while those where the g and b components should be don't. It's just that the values aren't sensible.

To get a sense of what the values are, I mapped the component values that end up in the frame buffer as a function of the values the shade test pattern uses. Here's the strange result: R, G and B as a function of input brightness The "Gray" axis is the value the component the shade test is using and the curves show the corresponding values for each component as they appear in the frame buffer.

I would love to hear from someone who has successfully used this camera module. It's probably something dumb I'm missing.

WangYuxin-esp commented 3 weeks ago

@dehne ,Hi, the SC101IOT camera sensor can be used by configured as init_camera(10000000, PIXFORMAT_YUV422, FRAMESIZE_HD, 2), refer to example.
And please check the configuration of SC101IOT in your configuration menu.

dehne commented 3 weeks ago

@WangYuxin-esp, Hello and thank you for writing. Although the initialization parameters weren't the problem -- I had used exactly the ones used in the example -- your post helped me discover my mistake.

I'm a little embarrassed to say it, but the trouble was that I had mistyped a name in the mapping between the GPIOs and the camera's data pins. Many hours spent looking in so many wrong places. Now, that I have found the problem, I see that the symptoms point directly to it!

This issue may be closed as a user error.

Thanks again for writing.

dehne commented 2 weeks ago

Issue resolved: User Error