1、前言
之前在STM32N6中實現(xiàn)了官方例程DCMIPP和CSI的移植,并且解決了CubeMX在CSI的BUG以及如何解決。
但是攝像頭獲取的是黑白圖片,本期我們介紹ISP并且利用STM32N6的ISP庫實現(xiàn)色彩調(diào)整。
圖像對比如下:
2、相機參數(shù)
IMX335是一款高性能的CMOS圖像傳感器,為了使其在不同的應(yīng)用場景中發(fā)揮最佳性能,需要根據(jù)具體需求進行相機參數(shù)的設(shè)置,就如同相機專業(yè)模式一樣,增益值影響圖像的亮度。較高的增益可以使圖像更亮,但也增加更多的噪聲。
曝光時間決定了傳感器捕捉光線的時間長度。較長的曝光時間可以使更多光線進入,使圖像更亮,但也可能導(dǎo)致運動模糊。色彩平衡和白平衡可以確保圖像的色彩準(zhǔn)確性。
因此在獲取圖像的基礎(chǔ)上如何調(diào)整相機參數(shù)便是一門深厚的學(xué)問。
IMX335可以設(shè)置增益,設(shè)置曝光等基本參數(shù)的功能,但是想要獲得高質(zhì)量圖像,就需要了解“圖像信號處理器”即ISP(Image Signal Processor)
3、Image Signal Processor
ISP是攝像頭系統(tǒng)中的核心芯片/模塊,負(fù)責(zé)將圖像傳感器(IMX335)輸出的原始信號(RAW Data)轉(zhuǎn)換為高質(zhì)量的可視化圖像。
其核心任務(wù)包括:色彩校正(如白平衡調(diào)整),降噪處理,自動曝光(AE)與自動對焦(AF),銳化與細(xì)節(jié)增強,動態(tài)范圍優(yōu)化(如HDR/WDR)。
ST推出其ISP工具:STM32 ISP IQTune
其是一款用于STM32微控制器的圖像信號處理器(ISP)調(diào)校軟件,用于圖像質(zhì)量優(yōu)化,支持實時預(yù)覽,自動調(diào)整和色彩分析。
它提供了三個平臺的客戶端以及為STM32N6專用的庫,本期我們移植X-CUBE-ISP到我們的STM32N6開發(fā)板中。
4、ISP-Lib
X-Cube-ISP主要包含了幾個.a靜態(tài)庫文件以及ISP的驅(qū)動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的回調(diào)函數(shù),其目的主要是獲取和設(shè)置傳感器的圖像參數(shù)信息。
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();
}
設(shè)置ISP的基本參數(shù),并且開啟ISP處理,之后我們進行ISP調(diào)整。
? ??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進行調(diào)整,就可以實現(xiàn)圖像色彩調(diào)整啦。