Make camera sensor auto-exposure faster, usable

This commit is contained in:
fruchti 2024-08-24 20:49:45 +02:00
parent e43202a113
commit 3f6016106b
3 changed files with 56 additions and 9 deletions

View file

@ -6,4 +6,13 @@
// Use a primitive autoexposure by shifting each frames luminosity based on the
// ratio of white to black pixels in the previous frames
// #define CONFIG_USE_EXPOSURE_CORRECTION
// #define CONFIG_USE_EXPOSURE_CORRECTION
// Capture a frame when it is within this tolerance of 50% black pixels
#define CONFIG_TOLERANCE 0.2
// Wait this number of frames before a frame is eligible for beaing captured
#define CONFIG_MIN_FRAMES 2
// Maximum number of frames to wait. Capture even if it is not within tolerance.
#define CONFIG_MAX_FRAMES 15

View file

@ -1,7 +1,6 @@
#include "ov7670.h"
#include "pinning.h"
#include "debug.h"
#include "config.h"
#define REG_GAIN 0x00
#define REG_BLUE 0x01
@ -127,12 +126,12 @@
#define REG_HAECC2 0xa0
#define REG_SCALING_PCLK_DELAY 0xa2
#define REG_NT_CTRL 0xa4
#define REG_BD50MAX 0xa5
#define REG_HAECC3 0xa6
#define REG_HAECC4 0xa7
#define REG_HAECC5 0xa8
#define REG_HAECC6 0xa9
#define REG_HAECC7 0xaa
#define REG_AECGMAX 0xa5
#define REG_LPH 0xa6
#define REG_UPL 0xa7
#define REG_TPL 0xa8
#define REG_TPH 0xa9
#define REG_NALG 0xaa
#define REG_BD60MAX 0xab
#define REG_STR_OPT 0xac
#define REG_STR_R 0xad
@ -161,6 +160,9 @@ static unsigned int BlackPixels = 0;
static volatile int ExposureCorrection = 0;
#endif
volatile unsigned int Camera_BlackPixelCounts[] = {0};
volatile int Camera_FinalFrameCount = -1;
static uint8_t ReadRegister(uint8_t reg)
{
while(I2C1->SR2 & I2C_SR2_BUSY);
@ -302,6 +304,24 @@ void Camera_Init(void)
WriteRegister(REG_COM14, 0x18 | 1);
WriteRegister(REG_SCALING_PCLK_DIV, 1);
// Set maximum gain ceiling
WriteRegister(REG_COM9, 0xca);
// Disable auto-exposure, enable auto-gain
WriteRegister(REG_COM8, 0xec);
// // Disable auto-gain, enable auto-exposure
// WriteRegister(REG_COM8, 0xe9);
// Use histogram-based auto-exposure
WriteRegister(REG_NALG, 0x94);
// Increase AEC speed:
// Decrease TPL but not less than UPL [default 0xc1] and increase TPH but
// not bigger than LPH [default 0xf0]
WriteRegister(REG_TPL, 0xc1);
WriteRegister(REG_TPH, 0xf0);
// Enable VSYNC interrupts. TIM3 is enabled at the first VSYNC.
FrameCount = 0;
Camera_Captured = 0;
@ -334,14 +354,28 @@ void TIM1_CC_IRQHandler(void)
#endif
// Check if the last frame's exposure is reasonable
if(FrameCount >= 5)
if(!Camera_Captured && FrameCount >= CONFIG_MIN_FRAMES
&& (
(BlackPixels > (int)(CAMERA_PIXELS / 2
- CAMERA_PIXELS * CONFIG_TOLERANCE)
&& BlackPixels < (int)(CAMERA_PIXELS / 2
+ CAMERA_PIXELS * CONFIG_TOLERANCE))
|| FrameCount >= CONFIG_MAX_FRAMES
))
{
Camera_Captured = 1;
Camera_FinalFrameCount = FrameCount;
// Disable everything
TIM3->CR1 = 0;
TIM1->CR1 = 0;
}
if(FrameCount < (int)(sizeof(Camera_BlackPixelCounts)
/ sizeof(Camera_BlackPixelCounts[0])))
{
Camera_BlackPixelCounts[FrameCount] = BlackPixels;
}
// Reset black pixel counter
BlackPixels = 0;

View file

@ -2,6 +2,7 @@
#include <stdlib.h>
#include "stm32f1xx.h"
#include "config.h"
#define CAMERA_IMAGE_WIDTH 160
#define CAMERA_IMAGE_HEIGHT 144
@ -10,4 +11,7 @@
extern volatile int Camera_Captured;
extern volatile unsigned int Camera_BlackPixelCounts[CONFIG_MAX_FRAMES];
extern volatile int Camera_FinalFrameCount;
void Camera_Init(void);