espressif / esp32-camera

Apache License 2.0
1.79k stars 622 forks source link

ESP-EYE +OV5640 - Vertical lines noise in the JPEG picture #172

Closed NathanKuo0821 closed 2 years ago

NathanKuo0821 commented 3 years ago

Hi I used the esp-eye + ov5640 to capture , i see the vertical lines and noise. Adjust the XCLK to 5/10/15/20 MHz has no effect. Does anyone know how to solve it?

Extra info: .xclk_freq_hz = 10000000, .pixel_format = PIXFORMAT_JPEG, .frame_size = FRAMESIZE_QSXGA,

dark

Thanks.

Wassasin commented 3 years ago

Same here.

45bc90e4-4a70-4c4f-9b0a-9e247e499543

me-no-dev commented 3 years ago

And here is what I see

capture

me-no-dev commented 3 years ago

I don't think that the issue is power, but I could be wrong. Image is taken at 10MHz XCLK QSXGA JPEG with the web server example in ESP-WHO

Wassasin commented 3 years ago

I will investigate with a larger batch this week, and will inspect the signal quality with a scope.

ghost commented 3 years ago

OK... now time to close this issue.

ghost commented 3 years ago

try using a power bank. OR Try chcking the camara's fraimrate and try again. OR Try removing the camara and clean the camara pins and insert it back. it might be a bad connection.

If it doesn't work, it is a problume in the code or the camara.

Responding to the issue to help.

raduprv commented 3 years ago

Try this: https://github.com/espressif/esp32-camera/issues/229

rotrico commented 3 years ago

I had a lot of noise, I reduced xclk_freq_hz from 20 Mhz to 5 Mhz and noise reduced noticeable (below 10 Mhz also you'll have to increase some timeouts in driver to avoid error messages). Also I tried #229 , it improves noise levels, but less than reducing xclk_freq_hz Some noise is inevitable in low light conditions and using cheap sensors like OV5640, try in outdoor in a sunny day, if you don't see noise, probably you're doing it ok and noise its due sensor. Also you can check sensor with an USB adapter to see if you see same problem using a full OS instead of an ESP32 (OV5640 works out of the box in Ubuntu).

raduprv commented 3 years ago

Reducing the clock will expose the pictures more, but it takes longer to get the picture from the sensor.

xenpac commented 3 years ago

@Wassasin did you do analyze a batch of cams? any results? i do have also a noise issue, looks like a fixed noise pattern. could be bad production lot.

github-actions[bot] commented 2 years ago

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

tve commented 2 years ago

Did anyone manage to get rid of the noise? I'm seeing the issue in very bright outdoor conditions.

I don't believe it's "pixel noise" because that wouldn't have such a vertical-line pattern, it would be more random (thermal) noise. I looks more to me like electrical noise/interference. Either the cheap ov5640 we get have crap sensors or the typical esp32-cam electrical environment is no good for this sensor (but then, why do the ov5640 not exhibit this?).

Here's a crop from a full-frame USXGA. The pattern in the lines is always the same, frame after frame. That makes me believe it's a sensor issue. I would expect the electrical noise to vary... Hard to tell...

(And, oh man, those tiny lenses are such a POS...) Screenshot from 2021-09-16 13-35-55

raduprv commented 2 years ago

Did you try my solutions? It is noise, and in your case the image looks so bad because it is compressed.

tve commented 2 years ago

I have not reduced the clock freq, it's at 16.5Mhz. I'll give that a shot, but it's not really a solution 'cause it has a direct impact on frame rate, which is already not exactly high. (Oh, and the fact that the quality of the image, besides the lines, is poor has a lot to do with the crap lens. I need to figure out whether it's possible to get a decent lens, but that is only worth it if I can make the lines go away...)

tve commented 2 years ago

I'm trying to troubleshoot this a bit further. Haven't hooked up the scope yet... I started by taking a look at the voltage regulators in the esp32-cam schematics. There's the main 3.3V regulator and then 2.8V and 1.2V regulators for AVDD and DVDD going to the image sensor in addition to the 3.3V for DOVDD. These are the digital core voltage, the analog voltage, and the I/O voltage respectively. The voltages were designed for the OV2640 and there's a liiitle problem with the OV5640, which is that DVDD needs to be 1.5V, not 1.2V. The reason it works anyway is that the OV5640 has an internal 1.5V regulator, which is enabled by default. So my understanding is that the 1.2V DVDD going to the sensor is unused. However, the 1.5V internal regulator uses DOVDD, and that is supposed to be 1.8V or 2.8V, not 3.3V (which is still within absolute max rating) and the data sheet has the following to say about the internal regulator (sec 2.7 Power Up Sequence):

If 1.8V is used for I/O power, using the internal DVDD is preferred. If 2.8V is used for I/O power, due to a high voltage drop at the internal DVDD regulator, there is a potential heat issue. Hence, for a 2.8V power system, OmniVision recommends using an external DVDD source.

I haven't done any experimental validation of any of this, but I know that the sensor gets bloody hot, to the point that the first thing I did was to stick it onto a heatsink. That still gets really hot! Obviously in an image sensor heat == noise...

I clearly have more testing to do, but I'm starting to wonder whether I'll have to do some voltage regulator surgery on one of my esp32-cam to see whether that fixes things...

tve commented 2 years ago

At the risk of conducting a monologue... I did some experiments, no success yet, but interesting findings... I first replaced the 1.2Vreg by a 1.5Vreg and switched the DVDD source from the internal regulator to the external one (for reference, set register 0x3031 to 0x08 for external, and 0x00 for internal). I cut the output trace from the 1.5Vreg and verified that if I switch to external Vreg the sensor cannot produce an image. Result in terms of noise: it's actually worse using the external regulator. So long for that theory.

I then added a second 3.3Vreg to the board and fed that to all the camera power, such that the original Vreg only powers ESP32 and PSRAM and a separate Vreg powers the sensor. Result in terms of noise: I can't see a difference. (Well, I can see an improvement in the scope but the image captured looks as bad as before.)

Sample images, first with internal Vreg: ov5640 int DVDD 2021-09-20 16-26-08 Second image using external Vreg ov5640 ext DVDD 2021-09-20 16-25-05

The OV5640 sensor I bought came with a tiny USB adapter board, so I figured I'd plug that in to see what it produces... I had actually done that at the beginning and then stole the 1.5V Vreg from that board 'cause I don't have any in my parts bin... But hey, since the sensor works with internal Vreg the board with stolen Vreg should still work, right? Well, here's the image it produces: ov5640 USB 2021-09-20 16-32-58 To say that it's infinitely better would be an infinite understatement... (I made sure it was captured at QSXGA resolution) Here's a pic of that USB board (you can see the missing Vreg in the upper right corner): IMG_20210920_163743 IMG_20210920_163259

How does that USB interface board do it? I have two hypotheses: better camera settings and different clock signals. The settings are clearly different, I either have to slug though the manual and see what could be improved or take an I2C capture from the USB board. Before doing that, I figure I'd check the signals going to the sensor: PCLK and MCLK. (I believe both are generated by the esp32, need to double-check.)

Turns out they look vastly different on the scope! The signals from the esp32 have very steep rise and fall times, running at 10Mhz PCLK and 16.5Mhz MCLK (actually, MCLK seems to toggle between two freq's). The signals from the USB interface chip look almost like sine waves, i.e., very slow rise and fall times, and run at 20Mhz and 12Mhz respectively.

So my preliminary conclusion is that either the sensor settings used by the esp32 code have "lots of room for improvement" or the very fast rise/fall times of the clocks cause issues. I think the easiest test at this point is probably to reduce the drive strength of the esp32 output pins and see whether that has an effect...

Edit: I forgot to add that the sensor gets much much less hot when using the USB interface board, even with internal Vreg and while streaming video, so "something is going on there". Correction: PCLK is driven by the ov5640, at least in the esp32-cam set-up. From the datasheet it looks like it could either way. Addition: I'm not liking XVCLK (CSI_MCLK), it's not regular. Here's a scope shot of 4 cycles where the 3rd is clearly shorter. I wonder whether that can cause noise, e.g. due to less sampling time or something like that. DS1104Z_2021-09-20_20:12:21

Update: I reduced the drive strength of XVCLK and the signal looks much less sharp on the scope but it has no effect on the image. What we're seeing must have something to do with the settings or the way the chip is used. There's also the issue of the excessive heating...

rotrico commented 2 years ago

Hi @tve , a few months ago I had same issues wit OV5640 I tested same sensors against ESP32-CAM (AI Thinker model) and an USB board to compare them, getting far better quality with USB (on a computer running Ubuntu with a tool to get images from webcams, "camorama", I think it was) Then I concluded that the quality difference was due PC image processing: in ESP32, OV5640 was returning a JPEG image created by OV5640. In USB, OV5640 was returning a raw image (I dont' remember format, but wasn't JPEG) and was computer who showed this stream on monitor and also allowed to convert it to JPEG and save it. In my case, as I didn't want to get any stream from camera (only take photos) I solved noise problem reducing xclk_freq_hz from 20 Mhz to 5 Mhz Also I found that besides inherent noise problem, those cheap OV5640 sensors have a very low quality: many of them have problems to get image in focus, areas permanently blurred, differences in image quality from sensor to sensor... Finally I decided to throw away OV5640 and try with OV3660 and a M5Stack Timer Camera X. It doesn't have same resolution that OV5640, but also it doesn't have noise problems and sensor quality is more consistent from sensor to sensor (different OV3660 sensors have comparable quality).

tve commented 2 years ago

@rotrico, thanks for the info! I did reduce XCLK to 5Mhz and you're correct that it reduces the noise. It also slows the frame rate down, which is an issue for me.

Interesting that the 3660 doesn't have the noise problem, it also has 1.4um pixels and seems almost identical to the ov5640 except for sensor area. Weird that it behaves better... I only have one ov5640, so I can't judge sample-to-sample variation.

WRT image quality, the lenses on these small sensors are crap and are not sharp except at the very center of the image. I'm planning on mounting an M12 lens to hopefully fix that.

I'm going to review the exposure and gain settings to see whether there's a problem there. Otherwise, perhaps it is the heat and electrical noise produced by the on-chip JPEG compression that causes the problems, although, I don't really see why that would be different between ov3660 and ov5640...

tve commented 2 years ago

I spent a bunch of hours trying different settings, especially of the black-level compensation, all to no avail. The noise remains what it is. The only thing that makes a difference is to reduce the clock rate as rotrico suggests. An additional good news / bad news is that actually, at 6Mhz VCLK, if I set the jpeg quality high I end up with ~450-480KB frame sizes and at that point the data transmission is pretty much balanced with the frame acquisition at ~0.8fps. The esp32 transmits at about 2.8mbps, which seems to be the max the arduino framework allows for (the wifi data rate is 72mpbs and it's sending 2872 bytes data packets, so it's the s/w stack or PSRAM access that limits).

tl;dr: if you want video that (mostly) doesn't have vertical streaks then reduce the clock rate to 6Mhz, crank up the jpeg quality, and "enjoy" 0.8fps...

Schaggo commented 2 years ago

Sorry, I only loosely followed the thread.

I had similar issues with an underpowered power source. How does your source look like(5V/3,3v, max amps)?

tve commented 2 years ago

If you had followed more closely ;-) you would have noticed that I redid the power regulators to try and improve things, to no avail... ;-)

rotrico commented 2 years ago

@tve I don't know if you're happy with your current results (0.8 fps). Maybe you could try some things to improve your solution: 1- You could reduce resolution and quality to get a higher fps stream (maybe VGA it's enough) and, when you wan to get a picture, select a higher resolution (3 or 5 Mpx) and take it. Some entry level smartphones use these strategy to get a decent stream when you open camera app to show a preview. 2- Pinephone uses OV5640 module and they get decent results from it. Source code isn't directly portable to ESP32, but maybe you can find some ideas to improve results: https://wiki.pine64.org/wiki/PinePhone https://xnux.eu/devices/feature/cam.html https://tuxphones.com/pinephone-camera-ov5640-linux-support-driver-autofocus-color-calibration/ 3- Finally, I don't know if for you is mandatory using an ESP32, maybe you could try a very different approach: discard ESP32 and use a Raspberry Pi Zero with an OV5640 attached to its USB port. As Pi runs a full Linux, it should support OV5640 out of the box, at least Ubuntu 18.04 supports it, Raspbian should do it.

tve commented 2 years ago

@rotrico Thanks for the excellent suggestions! I'm "happy" right now in that the 6Mhz clock rate is sufficient to produce images fast enough for the wifi transmission to consume, i.e., the sensor read-out speed is not the bottleneck. I may give optimizing the data transmission a shot, but I suspect that I'm just hitting the psram bandwidth limit. With the arduino stuff I'm not even sure how to check that the processor is running at 240Mhz and the psram at 80Mhz/QIO... (I'm using https://github.com/easytarget/esp32-cam-webserver, maybe there's a simple esp-idf app I could use instead that streams the video in mjpeg more efficiently.)

The pinephone suggestion is a good one. However, it uses a raw readout and does the debayering and follow-on processing in the phone cpu. There's an official linux driver for the ov5640, I looked at it and it uses the ov5640 setting verbatim from the app note. It would be worthwhile hacking esp32-camera to swap out the init sequence for the one from the app note. But that sounds like another day of work, at least...

WRT using something other than an esp32: I'm doing that :-). I do have a bunch of rPi with cameras, but at that point it's much easier to use a better sensor to begin with, no need for in-sensor jpg... :-)

Thanks for the suggestions and your work!

ConradWood commented 2 years ago

FWIW - I power my board with 3.3V and also encountered the annoying lines. I soldered a 1,000uF capacitor to the 3.3V and GND pin and that fixed it. YMMV of course.

Wassasin commented 2 years ago

My client has a large amount of OV5640's in use, and we notice just some units having this noise. They are discarded as being junk. I spent some time checking whether it was either a software or a hardware error, but with matching registers this still varies unit-by-unit. Our own hardware is not the problem, as plugging in a fresh OV5640 'solves' the issue.

YMMV.

tve commented 2 years ago

@Wassasin any tips on where to get 5640's that have a chance of being good? Or what to look for?

Grabber commented 1 year ago

What IOVDD are you using to power OV5640?

On Fri, Mar 18, 2022 at 11:57 AM Thorsten von Eicken < @.***> wrote:

@Wassasin https://github.com/Wassasin any tips on where to get 5640's that have a chance of being good? Or what to look for?

— Reply to this email directly, view it on GitHub https://github.com/espressif/esp32-camera/issues/172#issuecomment-1072490999, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAD247OKE4ITX6F2AGY2ZTVASKUBANCNFSM4QLOVDRA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Regards,

Luiz Vitor Martinez Cardoso

"The only limits are the ones you place upon yourself"

GTCLive commented 1 year ago

The sensor manufacturer outlines the requirement for PGND(pwr ground), DGND and AGND. These needs to be tied up together, I've made the bridge near the VCC/PGND input far from everything else. Using a 24MHz oscillator (XO) powered on by 2.8V for XCLK. Everything drives from quality 10u tantalums (TAJR106K006RNJ). They aren't the easiest boards to design and route however if the requirements are followed it works flawlessly, nothing wrong with the sensor.

Side note; I'm not familiar with the ESP32-CAM, but guessing if noise is an issue, 'it is what it is', and can't be solved.

gnd ^ Mandatory

zekageri commented 10 months ago

I have a really bad screen tearing with this sensor.

Screenshot_20230926_210627_Chrome.jpg

Screenshot_20230926_210621_Chrome.jpg

zekageri commented 10 months ago

Here is a video to better demonstrate my problem

https://streamable.com/n5z60r

zekageri commented 10 months ago

So i adjusted my settings like so

config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;

config.xclk_freq_hz = 22000000;
config.frame_size = FRAMESIZE_SVGA;
config.pixel_format = PIXFORMAT_JPEG;  // for streaming
config.grab_mode = CAMERA_GRAB_LATEST;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 8;
config.fb_count = 3;

It streams fairly well now but i can't take a decent picture

Here is my async webserver code for it

server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
    camera_fb_t * fb = esp_camera_fb_get();
    if(!fb){
        request->send(500, "text/plain", "Camera capture failed");
        return;
    }
    char ts[32];
    snprintf(ts, 32, "%ld.%06ld", fb->timestamp.tv_sec, fb->timestamp.tv_usec);
    AsyncWebServerResponse *response = request->beginResponse_P(200, "image/jpeg", fb->buf, fb->len);
    response->addHeader("Content-Disposition", "inline; filename=capture.jpg");
    response->addHeader("Access-Control-Allow-Origin", "*");
    response->addHeader("X-Timestamp", ts);
    request->send(response);
    esp_camera_fb_return(fb);
});

The picture is really bad

image

What can be the problem?

me-no-dev commented 9 months ago

XCLK of 22MHz could be the problem. Try 20MHz or less

zekageri commented 9 months ago

Yeah, it was XCLK but for some reason the picute on the left side is really white.

https://github.com/espressif/arduino-esp32/issues/8683