@Calin @m5-docs Thanks all, I guess I just got a bad camera.
I tried using a different camera and the image quality is fine using this example: https://github.com/espressif/esp-who/tree/master/examples/single_chip/camera_web_server.
I have a "model A" camera and I wasn't able to get the code at https://github.com/m5stack/m5stack-cam-psram to work using the ModeA branch and setting the flag #define M5_CAM_KIND 1.