前言
之前在STM32N6中实现了官方例程DCMIPP和CSI的移植,并且解决了CubeMX在CSI的BUG以及如何解决。

但是摄像头获取的是黑白图片,本期我们介绍ISP并且利用STM32N6的ISP库实现色彩调整。
图像对比如下:

相机参数
IMX335是一款高性能的CMOS图像传感器,为了使其在不同的应用场景中发挥最佳性能,需要根据具体需求进行相机参数的设置,就如同相机专业模式一样,增益值影响图像的亮度。较高的增益可以使图像更亮,但也增加更多的噪声。
曝光时间决定了传感器捕捉光线的时间长度。较长的曝光时间可以使更多光线进入,使图像更亮,但也可能导致运动模糊。色彩平衡和白平衡可以确保图像的色彩准确性。
因此在获取图像的基础上如何调整相机参数便是一门深厚的学问。

IMX335可以设置增益,设置曝光等基本参数的功能,但是想要获得高质量图像,就需要了解“图像信号处理器”即ISP(Image Signal Processor)
Image Signal Processor
ISP是摄像头系统中的核心芯片/模块,负责将图像传感器(IMX335)输出的原始信号(RAW Data)转换为高质量的可视化图像。
其核心任务包括:色彩校正(如白平衡调整),降噪处理,自动曝光(AE)与自动对焦(AF),锐化与细节增强,动态范围优化(如HDR/WDR)。
ST推出其ISP工具:STM32 ISP IQTune

其是一款用于STM32微控制器的图像信号处理器(ISP)调校软件,用于图像质量优化,支持实时预览,自动调整和色彩分析。

它提供了三个平台的客户端以及为STM32N6专用的库,本期我们移植X-CUBE-ISP到我们的STM32N6开发板中。
ISP-Lib

X-Cube-ISP主要包含了几个.a静态库文件以及ISP的驱动API。

将所有文件添加到工程中,修改isp_conf.h和isp_param_conf.h的文件名(去掉templete)。
static ISP_StatusTypeDef GetSensorInfoHelper(uint32_t Instance, ISP_SensorInfoTypeDef *SensorInfo)
{
UNUSED(Instance);
return (ISP_StatusTypeDef) IMX335_GetSensorInfo(&IMX335Obj, (IMX335_SensorInfo_t *) SensorInfo);
}
/**
* @brief ISP Middleware helper. Camera gain setter
* @retval ISP Status
*/
static ISP_StatusTypeDef SetSensorGainHelper(uint32_t Instance, int32_t Gain)
{
UNUSED(Instance);
isp_gain = Gain;
return (ISP_StatusTypeDef) IMX335_SetGain(&IMX335Obj, Gain);
}
/**
* @brief ISP Middleware helper. Camera gain getter
* @retval ISP Status
*/
static ISP_StatusTypeDef GetSensorGainHelper(uint32_t Instance, int32_t *Gain)
{
UNUSED(Instance);
*Gain = isp_gain;
return ISP_OK;
}
/**
* @brief ISP Middleware helper. Camera exposure setter
* @retval ISP Status
*/
static ISP_StatusTypeDef SetSensorExposureHelper(uint32_t Instance, int32_t Exposure)
{
UNUSED(Instance);
isp_exposure = Exposure;
return (ISP_StatusTypeDef) IMX335_SetExposure(&IMX335Obj, Exposure);
}
/**
* @brief ISP Middleware helper. Camera exposure getter
* @retval ISP Status
*/
static ISP_StatusTypeDef GetSensorExposureHelper(uint32_t Instance, int32_t *Exposure)
{
UNUSED(Instance);
*Exposure = isp_exposure;
return ISP_OK;
}
定义ISP的回调函数,其目的主要是获取和设置传感器的图像参数信息。
ISP_AppliHelpersTypeDef appliHelpers = {0};
ISP_StatAreaTypeDef statArea = {0};
appliHelpers.GetSensorInfo = GetSensorInfoHelper;
appliHelpers.SetSensorGain = SetSensorGainHelper;
appliHelpers.GetSensorGain = GetSensorGainHelper;
appliHelpers.SetSensorExposure = SetSensorExposureHelper;
appliHelpers.GetSensorExposure = GetSensorExposureHelper;
statArea.X0 = 0;
statArea.Y0 = 0;
statArea.XSize = 2592;
statArea.YSize = 1944;
/* Initialize the Image Signal Processing middleware */
if(ISP_Init(&hcamera_isp, &hdcmipp, 0, &appliHelpers, &statArea, ISP_IQParamCacheInit[0]) != ISP_OK)
{
Error_Handler();
}
if (HAL_DCMIPP_CSI_PIPE_Start(&hdcmipp, DCMIPP_PIPE1, DCMIPP_VIRTUAL_CHANNEL0 , BUFFER_ADDRESS, DCMIPP_MODE_CONTINUOUS) != HAL_OK)
{
Error_Handler();
}
if (ISP_Start(&hcamera_isp) != ISP_OK)
{
Error_Handler();
}
设置ISP的基本参数,并且开启ISP处理,之后我们进行ISP调整。
while(NbMainFrames < 60)
{
if (ISP_BackgroundProcess(&hcamera_isp) != ISP_OK)
{
HAL_GPIO_TogglePin(GPIOG,GPIO_PIN_10);
}
}
void HAL_DCMIPP_PIPE_VsyncEventCallback(DCMIPP_HandleTypeDef *hdcmipp, uint32_t Pipe)
{
UNUSED(hdcmipp);
/* Update the frame counter and call the ISP statistics handler */
switch (Pipe)
{
case DCMIPP_PIPE0 :
ISP_IncDumpFrameId(&hcamera_isp);
break;
case DCMIPP_PIPE1 :
ISP_IncMainFrameId(&hcamera_isp);
ISP_GatherStatistics(&hcamera_isp);
break;
case DCMIPP_PIPE2 :
ISP_IncAncillaryFrameId(&hcamera_isp);
break;
}
}
传入60帧图像,让ISP进行调整,就可以实现图像色彩调整啦。