6 君正ISP的封装

概述

        ISP,即图像信号处理单元,主要包含图像效果设置,模式切换以及Sensor的注册、添加、删除等操作。ISP模块与数据流无关,不需要进行绑定,仅作用于效果参数设置及Sensor控制。

ISP接口类

        君正的ISP模块除了能够设置亮度、对比度、饱和度等图像效果参数外,还可以设置日夜切换模式。日夜切换模式一般根据什么来设置呢?

        主要有三种方法:第一种是IPC上有硬光敏,且软件能够读取硬光敏的ADC值;第二种是IPC上有硬光敏,但软件无法读取硬光敏的ADC值,只能通过某个GPIO口读取是白天还是黑夜;第三种是IPC上没有硬光敏,只能通过对视频图像的颜色信息、曝光信息等进行统计分析,来判断当前是白天还是黑夜(这种方法也被称为“软光敏”)。

        ISP接口类主要有以下几个接口:

        1、初始化接口,用于传入初始化参数。

        2、设置某个通道的色调百分比值,范围为0到100。

        3、设置某个通道的对比度百分比值,范围为0到100。

        4、设置某个通道的亮度百分比值,范围为0到100。

        5、设置某个通道的饱和度百分比值,范围为0到100。

        6、设置某个通道的清晰度百分比值,范围为0到100。

        7、设置某个通道的日夜模式,日夜模式一共有五种,分别为:黑白模式关、黑白模式开、黑白模式自动、全彩模式、智能模式。黑白模式关表示强制不使用红外灯;黑白模式开表示强制使用红外灯;黑白模式自动表示白天不使用红外灯,夜晚使用红外灯;全彩模式表示夜晚自动打开白光灯,加强画面色彩效果;智能模式表示夜晚默认打开红外灯,当检测到移动或人形时,自动打开白光灯。

        8、设置某个通道的翻转模式,翻转模式一共有四种,分别为:不翻转、水平翻转、垂直翻转、水平垂直翻转。

        9、设置某个通道的抗闪烁模式,抗闪烁模式一共有三种,分别为:不使能抗闪烁、50Hz抗闪烁、60Hz抗闪烁。

        10、设置某个通道红外滤光片的使能情况,夜晚时使能,白天时不使能,该接口主要用于产线工具使用。

        11、设置某个通道红外灯的使能情况,夜晚时使能,白天时不使能,该接口主要用于产线工具使用。

        12、判断当前某个通道的日夜模式是否为夜晚。

        13、设置某个通道是否检测到了智能报警事件。当日夜模式为智能模式时,如果检测到了智能报警事件,则自动打开白光灯。

        ISP接口类的头文件如下:

#pragma once#include "HP_MPPTypes.h"class CHP_ISP
{
public:virtual int Init(const TMppIspParam &param) = 0;virtual int SetHuePercent(unsigned int uiCameraChannel, unsigned char ucPercent) = 0;virtual int SetContrastPercent(unsigned int uiCameraChannel, unsigned char ucPercent) = 0;virtual int SetBrightnessPercent(unsigned int uiCameraChannel, unsigned char ucPercent) = 0;virtual int SetSaturationPercent(unsigned int uiCameraChannel, unsigned char ucPercent) = 0;virtual int SetSharpnessPercent(unsigned int uiCameraChannel, unsigned char ucPercent) = 0;virtual int SetNightVisionMode(unsigned int uiCameraChannel, IMppNightVisionMode mode) = 0;virtual int SetFlipMode(unsigned int uiCameraChannel, IMppIspFlipMode mode) = 0;virtual int SetAntiFlickerMode(unsigned int uiCameraChannel, IMppAntiflickerMode mode) = 0;virtual int SetIrFilter(unsigned int uiCameraChannel, bool bNight) = 0;virtual int SetIrLight(unsigned int uiCameraChannel, bool bNight) = 0;virtual bool IsNight(unsigned int uiCameraChannel) = 0;virtual int SetSmartEventDetected(unsigned int uiCameraChannel, bool bDetected) = 0;protected:CHP_ISP() {}virtual ~CHP_ISP() {}
};

        Init接口中,TMppIspParam结构体的定义如下:

typedef int(*CALLBACK_CUSTOM_SWITCH_IR_FILTER)(unsigned int uiCameraChannel, bool bNight, void *pContext);
typedef void(*CALLBACK_SWITCH_WHITE_LIGHT)(unsigned int uiCameraChannel, bool bOn, void *pContext);
typedef void(*CALLBACK_GET_WHITE_LIGHT_STATUS)(unsigned int uiCameraChannel, bool &bOpenForEver, bool &bIsOn, bool &bTwinkle, void *pContext);enum IMppDayNightDetectMode
{MppDayNightDetectMode_ADC,MppDayNightDetectMode_GPIO,MppDayNightDetectMode_Soft,MppDayNightDetectMode_Count
};typedef struct _TMppCameraAdcInfo 
{_TMppCameraAdcInfo(){nAdcIndex = 0;nSwitchToDayAdc = 200;nSwitchToNightAdc = 80;}int nAdcIndex;int nSwitchToDayAdc;int nSwitchToNightAdc;
}TMppCameraAdcInfo;typedef struct _TMppCameraGpioInfo 
{_TMppCameraGpioInfo(){uiDayNightDetectGpio = 0;bDayNightDetectGpioLowDay = false;}unsigned int uiDayNightDetectGpio;bool bDayNightDetectGpioLowDay;
}TMppCameraGpioInfo;typedef struct _TMppCameraSoftInfo 
{_TMppCameraSoftInfo(){uiSwitchToNightEv = 60000;uiSwitchToDayEv = 8000;uiBlueGainDiffBetweenCurAndMin = 15;uiBlueGainDiffBetweenCurAndMax = 15;}unsigned int uiSwitchToNightEv;unsigned int uiSwitchToDayEv;unsigned int uiBlueGainDiffBetweenCurAndMin;unsigned int uiBlueGainDiffBetweenCurAndMax;
}TMppCameraSoftInfo;typedef struct _TMppIspCameraParam 
{_TMppIspCameraParam(){uiIrFilterPGpio = 0;uiIrFilterNGpio = 0;uiIrLightGpio = 0;detectMode = MppDayNightDetectMode_ADC;}unsigned int uiIrFilterPGpio;unsigned int uiIrFilterNGpio;unsigned int uiIrLightGpio;IMppDayNightDetectMode detectMode;TMppCameraSoftInfo softInfo;union{TMppCameraAdcInfo adcInfo;TMppCameraGpioInfo gpioInfo;};
}TMppIspCameraParam;typedef std::vector<TMppIspCameraParam> TMppIspCameraParamVector;typedef struct _TMppIspParam 
{_TMppIspParam(){pCbCustomSwitchIrFilter = NULL;pCbSwitchWhiteLight = NULL;pCbGetWhiteLightStatus = NULL;pCbContext = NULL;pLogger = NULL;}TMppIspCameraParamVector vctCamera;CALLBACK_CUSTOM_SWITCH_IR_FILTER pCbCustomSwitchIrFilter;CALLBACK_SWITCH_WHITE_LIGHT pCbSwitchWhiteLight;CALLBACK_GET_WHITE_LIGHT_STATUS pCbGetWhiteLightStatus;void *pCbContext;CHP_Logger *pLogger;
}TMppIspParam;

        在TMppCameraAdcInfo结构体中,需要给出ADC的通道号、由夜晚切换到白天的ADC阈值、由白天切换到夜晚的ADC阈值。

        在TMppCameraGpioInfo结构体中,需要给出日夜切换的GPIO管脚、白天是否用低电平表示等参数。

        在TMppCameraSoftInfo结构体中,需要给出由白天切换到夜晚的EV阈值、由夜晚切换到白天的EV阈值、以及蓝色增益偏移量的最小最大值等参数。

        在TMppIspCameraParam结构体中,需要给出红外滤光片的两个GPIO管脚、白光灯的GPIO管脚、日夜探测模式等参数。由于使用硬光敏时,也需要使用软光敏进行辅助,因此softInfo变量没有放在共用体中。

        在TMppIspParam结构体中,需要给出每个通道的摄像头参数信息、自定义红外滤光片切换的回调函数、切换白光灯的回调函数、获取白光灯状态的回调函数等。

ADC的封装

        在君正芯片方案中,如果要使用ADC,需要先在内核中按下图进行配置。

        配置完成之后,接下来需要编写ADC辅助类,用于读取某个ADC通道的值。

        ADC辅助类的头文件AdcAux.h如下:

#pragma onceclass CAdcAux
{
public:CAdcAux();~CAdcAux();int Open(unsigned int uiIndex);void Close();int Enable();int Disable();int GetValue(int &nValue);private:int m_nFd;
};

        ADC辅助类的实现文件AdcAux.cpp如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>#include "HP_MPPErrorCode.h"
#include "AdcAux.h"#define ADC_AUX_CMD_ENABLE                                  0
#define ADC_AUX_CMD_DISABLE                                 1
#define ADC_AUX_CMD_SET_VREF                                2
#define ADC_AUX_STD_VREF_VALUE                              1800#if defined(CHIP_T31)#define ADC_AUX_DEV_PATH                            "/dev/jz_adc_aux_"
#elif defined(CHIP_T40)#define ADC_AUX_DEV_PATH                            "/dev/ingenic_adc_aux_"
#else#define ADC_AUX_DEV_PATH                            "/dev/jz_adc_aux_"
#endifCAdcAux::CAdcAux() : m_nFd(-1)
{NULL;
}CAdcAux::~CAdcAux()
{Disable();Close();
}int CAdcAux::Open(unsigned int uiIndex)
{int nRet = 0;char pszFile[256] = { 0 };sprintf(pszFile, "%s%u", ADC_AUX_DEV_PATH, uiIndex);m_nFd = open(pszFile, O_RDONLY);if (m_nFd < 0){nRet = E_MPP_File;}else{int nRef = ADC_AUX_STD_VREF_VALUE;nRet = ioctl(m_nFd, ADC_AUX_CMD_SET_VREF, &nRef);if (nRet != 0){Close();}}return nRet;
}void CAdcAux::Close()
{if (m_nFd >= 0){close(m_nFd);m_nFd = -1;}
}int CAdcAux::Enable()
{if (m_nFd < 0){return E_MPP_WrongState;}return ioctl(m_nFd, ADC_AUX_CMD_ENABLE);
}int CAdcAux::Disable()
{if (m_nFd < 0){return E_MPP_WrongState;}return ioctl(m_nFd, ADC_AUX_CMD_DISABLE);
}int CAdcAux::GetValue(int &nValue)
{if (m_nFd < 0){return E_MPP_WrongState;}int nValueTemp = 0;int nRet = read(m_nFd, &nValueTemp, sizeof(nValueTemp));if (nRet != sizeof(nValueTemp)){nRet = E_MPP_File;}else{nRet = 0;nValue = nValueTemp;}return nRet;
}

ISP实现类

        ISP实现类派生于ISP接口类,也派生于线程基类。ISP实现类的头文件如下:

#pragma once#include <HP_Base/HP_BaseThread.h>
#include <HP_Base/HP_Mutex.h>#include "HP_ISP.h"
#include "MPP_API_Base.h"class CISP : public CHP_ISP, public CHP_BaseThread
{
public:static void Open(CMppApi_Base *pApi);static CISP *&Singleton();static void Close();virtual int Init(const TMppIspParam &param);virtual int SetHuePercent(unsigned int uiCameraChannel, unsigned char ucPercent);virtual int SetContrastPercent(unsigned int uiCameraChannel, unsigned char ucPercent);virtual int SetBrightnessPercent(unsigned int uiCameraChannel, unsigned char ucPercent);virtual int SetSaturationPercent(unsigned int uiCameraChannel, unsigned char ucPercent);virtual int SetSharpnessPercent(unsigned int uiCameraChannel, unsigned char ucPercent);virtual int SetNightVisionMode(unsigned int uiCameraChannel, IMppNightVisionMode mode);virtual int SetFlipMode(unsigned int uiCameraChannel, IMppIspFlipMode mode);virtual int SetAntiFlickerMode(unsigned int uiCameraChannel, IMppAntiflickerMode mode);virtual int SetIrFilter(unsigned int uiCameraChannel, bool bNight);virtual int SetIrLight(unsigned int uiCameraChannel, bool bNight);virtual bool IsNight(unsigned int uiCameraChannel);virtual int SetSmartEventDetected(unsigned int uiCameraChannel, bool bDetected);protected:CISP(CMppApi_Base *pApi);virtual ~CISP();virtual unsigned int Run();private:typedef struct _TIspCameraWorkAdcInfo{_TIspCameraWorkAdcInfo(){bOpened = false;uiOpenTryCount = 0;pAdc = NULL;}bool bOpened;unsigned int uiOpenTryCount;void *pAdc;}TIspCameraWorkAdcInfo;typedef struct _TIspCameraWorkSoftInfo{_TIspCameraWorkSoftInfo(){uiGbGainMin = 0;uiGbGainMax = 0;uiLastCheckTick = 0;}unsigned int uiGbGainMin;unsigned int uiGbGainMax;unsigned int uiLastCheckTick;}TIspCameraWorkSoftInfo;typedef struct _TIspCameraWorkInfo{_TIspCameraWorkInfo(){bNight = false;mode = MppNightVisionMode_BlackWhiteOff;bSmartEventLastDetected = false;}bool bNight;IMppNightVisionMode mode;bool bSmartEventLastDetected;unsigned int uiDayCount;unsigned int uiNightCount;union{TIspCameraWorkAdcInfo adc;TIspCameraWorkSoftInfo soft;};}TIspCameraWorkInfo;typedef std::vector<TIspCameraWorkInfo> TIspCameraWorkInfoVector;void Work_ADC(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo);void Work_GPIO(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo);void Work_Soft(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo);void SwitchDayNight(unsigned int uiCameraChannel, bool bNight, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo);void SwitchToNight(unsigned int uiCameraChannel, TIspCameraWorkInfo &cwInfo, bool bNight);void SwitchToDay(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo, bool *pbNight = NULL);void SetIrNight(unsigned int uiCameraChannel, bool bNight);void SetNightMode(unsigned int uiCameraChannel, bool bNight);void SwitchWhiteLight(unsigned int uiCameraChannel, bool bOn);void SetNightVisionMode_Impl(unsigned int uiCameraChannel, IMppNightVisionMode mode, bool bNight);void GetGainThreshold(unsigned int uiCameraChannel, unsigned int &uiMin, unsigned int &uiMax);private:static CISP *m_pThis;CMppApi_Base *m_pApi;TMppIspParam m_param;TIspCameraWorkInfoVector m_vctWorkInfo;CHP_Mutex m_mutexWork;
};

        可以看到,有一个TIspCameraWorkInfoVector的成员变量m_vctWorkInfo,用于保存每个摄像头的工作信息。每个摄像头的工作信息包括:当前是否为夜晚、当前的日夜模式、上一次是否检测到了智能报警事件、判定为白天的次数、判定为夜晚的次数、ADC信息、软光敏信息等。

        ADC信息TIspCameraWorkAdcInfo中,包括:ADC辅助类的指针、ADC辅助类是否已打开、ADC辅助类打开尝试的次数等。

        软光敏信息TIspCameraWorkSoftInfo中,包括:颜色增益的最小最大值、上一次检测的时间戳等。

        ISP实现类的实现文件如下:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>#include <HP_Base/HP_Utils.h>#include "ISP.h"
#include "AdcAux.h"
#include "HP_GPIOUtils.h"CISP *CISP::m_pThis = NULL;CISP::CISP(CMppApi_Base *pApi) : CHP_ISP(), CHP_BaseThread(), m_pApi(pApi)
{NULL;
}CISP::~CISP()
{CHP_BaseThread::Stop();for (unsigned int i = 0; i < m_vctWorkInfo.size(); i++){TIspCameraWorkInfo &cwInfo = m_vctWorkInfo[i];TMppIspCameraParam &cp = m_param.vctCamera[i];if (cp.detectMode == MppDayNightDetectMode_ADC && cwInfo.adc.pAdc != NULL){delete (CAdcAux *)cwInfo.adc.pAdc;cwInfo.adc.pAdc = NULL;}}
}void CISP::Open(CMppApi_Base *pApi)
{if (m_pThis == NULL){m_pThis = new CISP(pApi);}
}CISP *&CISP::Singleton()
{return m_pThis;
}void CISP::Close()
{if (m_pThis != NULL){delete m_pThis;m_pThis = NULL;}
}int CISP::Init(const TMppIspParam &param)
{unsigned int uiMaxCameraCount = 1;
#if defined(CHIP_T40)uiMaxCameraCount = 2;
#endifif (param.vctCamera.empty() || param.vctCamera.size() > uiMaxCameraCount){CHP_Logger::Error(param.pLogger, "isp camera size invalid: %u, %u", param.vctCamera.size(), uiMaxCameraCount);return E_MPP_Param;}for (unsigned int i = 0; i < param.vctCamera.size(); i++){const TMppIspCameraParam &cp = param.vctCamera[i];if (cp.detectMode >= MppDayNightDetectMode_Count){CHP_Logger::Error(param.pLogger, "isp camera detect mode invalid: %u, %u", i, cp.detectMode);return E_MPP_Param;}if (cp.softInfo.uiSwitchToNightEv <= cp.softInfo.uiSwitchToDayEv){CHP_Logger::Error(param.pLogger, "isp camera soft exposure value invalid: %u, %u, %u", i, cp.softInfo.uiSwitchToNightEv, cp.softInfo.uiSwitchToDayEv);return E_MPP_Param;}if (cp.detectMode == MppDayNightDetectMode_ADC && cp.adcInfo.nSwitchToDayAdc <= cp.adcInfo.nSwitchToNightAdc){CHP_Logger::Error(param.pLogger, "isp camera adc value invalid: %u, %d, %d", i, cp.adcInfo.nSwitchToDayAdc, cp.adcInfo.nSwitchToNightAdc);return E_MPP_Param;}if (cp.detectMode == MppDayNightDetectMode_GPIO && cp.gpioInfo.uiDayNightDetectGpio == 0){CHP_Logger::Error(param.pLogger, "isp camera gpio invalid: %u", i);return E_MPP_Param;}}if (m_pApi == NULL || !m_param.vctCamera.empty()){CHP_Logger::Error(param.pLogger, "isp has been inited: %u", m_param.vctCamera.size());return E_MPP_WrongState;}for (unsigned int i = 0; i < param.vctCamera.size(); i++){const TMppIspCameraParam &cp = param.vctCamera[i];int nRet = CHP_GPIOUtils::Init(cp.uiIrFilterPGpio);if (nRet != 0){CHP_Logger::Warn(param.pLogger, "isp camera ir filter p gpio init failed: %u, %d", i, nRet);}nRet = CHP_GPIOUtils::Init(cp.uiIrFilterNGpio);if (nRet != 0){CHP_Logger::Warn(param.pLogger, "isp camera ir filter n gpio init failed: %u, %d", i, nRet);}nRet = CHP_GPIOUtils::Init(cp.uiIrLightGpio);if (nRet != 0){CHP_Logger::Warn(param.pLogger, "isp camera ir light gpio init failed: %u, %d", i, nRet);}if (cp.detectMode == MppDayNightDetectMode_GPIO){nRet = CHP_GPIOUtils::Init(cp.gpioInfo.uiDayNightDetectGpio, false);if (nRet != 0){CHP_Logger::Warn(param.pLogger, "isp camera day night detect gpio init failed: %u, %d", i, nRet);}}SetIrNight(i, false);TIspCameraWorkInfo cwInfo;cwInfo.mode = MppNightVisionMode_BlackWhiteOff;if (cp.detectMode == MppDayNightDetectMode_ADC){cwInfo.adc.pAdc = new CAdcAux();}m_vctWorkInfo.push_back(cwInfo);}m_param = param;CHP_BaseThread::Start();CHP_Logger::Info(param.pLogger, "isp init ok");return 0;
}int CISP::SetHuePercent(unsigned int uiCameraChannel, unsigned char ucPercent)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}return m_pApi->Isp_SetHue(ucPercent, uiCameraChannel);
}int CISP::SetContrastPercent(unsigned int uiCameraChannel, unsigned char ucPercent)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}return m_pApi->Isp_SetContrast(ucPercent, uiCameraChannel);
}int CISP::SetBrightnessPercent(unsigned int uiCameraChannel, unsigned char ucPercent)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}return m_pApi->Isp_SetBrightness(ucPercent, uiCameraChannel);
}int CISP::SetSaturationPercent(unsigned int uiCameraChannel, unsigned char ucPercent)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}return m_pApi->Isp_SetSaturation(ucPercent, uiCameraChannel);
}int CISP::SetSharpnessPercent(unsigned int uiCameraChannel, unsigned char ucPercent)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}return m_pApi->Isp_SetSharpness(ucPercent, uiCameraChannel);
}int CISP::SetNightVisionMode(unsigned int uiCameraChannel, IMppNightVisionMode mode)
{if (uiCameraChannel >= m_param.vctCamera.size() || mode >= MppNightVisionMode_Count){return E_MPP_Param;}if (m_param.pCbSwitchWhiteLight == NULL && (mode == MppNightVisionMode_FullColor || mode == MppNightVisionMode_Smart)){CHP_Logger::Warn(m_param.pLogger, "isp night vision mode not support: %u, %u", uiCameraChannel, mode);return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}int nRet = 0;m_mutexWork.Lock();TIspCameraWorkInfo &cwInfo = m_vctWorkInfo[uiCameraChannel];if (cwInfo.mode != mode){cwInfo.mode = mode;SetNightVisionMode_Impl(uiCameraChannel, mode, cwInfo.bNight);CHP_Logger::Info(m_param.pLogger, "isp night vision mode change to %u", mode);}m_mutexWork.Unlock();return nRet;
}int CISP::SetFlipMode(unsigned int uiCameraChannel, IMppIspFlipMode mode)
{if (uiCameraChannel >= m_param.vctCamera.size() || mode >= MppIspFlipMode_Count){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}int nRet = 0;switch (mode){case MppIspFlipMode_None:nRet = m_pApi->Isp_SetHorVerFlip(false, uiCameraChannel);break;case MppIspFlipMode_Hor:nRet = m_pApi->Isp_SetHorFlip(true, uiCameraChannel);break;case MppIspFlipMode_Ver:nRet = m_pApi->Isp_SetVerFlip(true, uiCameraChannel);break;case MppIspFlipMode_HorVer:nRet = m_pApi->Isp_SetHorVerFlip(true, uiCameraChannel);break;default:break;}return nRet;
}int CISP::SetAntiFlickerMode(unsigned int uiCameraChannel, IMppAntiflickerMode mode)
{if (uiCameraChannel >= m_param.vctCamera.size() || mode >= MppAntiflickerMode_Count){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}return m_pApi->Isp_SetAntiFlicker(mode, uiCameraChannel);
}int CISP::SetIrFilter(unsigned int uiCameraChannel, bool bNight)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_param.pCbCustomSwitchIrFilter != NULL){return m_param.pCbCustomSwitchIrFilter(uiCameraChannel, bNight, m_param.pCbContext);}TMppIspCameraParam &cp = m_param.vctCamera[uiCameraChannel];if (cp.uiIrFilterPGpio == 0 || cp.uiIrFilterNGpio == 0){return E_MPP_NotSupport;}char pszFile[256] = {0};sprintf(pszFile, "/sys/class/gpio/gpio%u/value", cp.uiIrFilterPGpio);int nFileP = open(pszFile, O_RDWR);sprintf(pszFile, "/sys/class/gpio/gpio%u/value", cp.uiIrFilterNGpio);int nFileN = open(pszFile, O_RDWR);if (bNight){write(nFileP, "1", 1);write(nFileN, "0", 1);}else{write(nFileP, "0", 1);write(nFileN, "1", 1);}usleep(100 * 1000);if (bNight){write(nFileP, "0", 1);write(nFileN, "1", 1);}else{write(nFileP, "1", 1);write(nFileN, "0", 1);}usleep(100 * 1000);write(nFileP, "0", 1);write(nFileN, "0", 1);close(nFileP);close(nFileN);return 0;
}int CISP::SetIrLight(unsigned int uiCameraChannel, bool bNight)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}TMppIspCameraParam &cp = m_param.vctCamera[uiCameraChannel];if (cp.uiIrLightGpio == 0){return E_MPP_NotSupport;}return CHP_GPIOUtils::SetValue(cp.uiIrLightGpio, bNight);
}bool CISP::IsNight(unsigned int uiCameraChannel)
{bool bNight = false;if (uiCameraChannel < m_vctWorkInfo.size()){TIspCameraWorkInfo &cwInfo = m_vctWorkInfo[uiCameraChannel];bNight = cwInfo.bNight;}return bNight;
}int CISP::SetSmartEventDetected(unsigned int uiCameraChannel, bool bDetected)
{if (uiCameraChannel >= m_param.vctCamera.size()){return E_MPP_Param;}if (m_pApi == NULL){return E_MPP_WrongState;}m_mutexWork.Lock();TIspCameraWorkInfo &cwInfo = m_vctWorkInfo[uiCameraChannel];bool bLastDetected = cwInfo.bSmartEventLastDetected;cwInfo.bSmartEventLastDetected = bDetected;if (cwInfo.mode == MppNightVisionMode_Smart && cwInfo.bNight){if (!bLastDetected){if (bDetected){SetNightMode(uiCameraChannel, false);SwitchWhiteLight(uiCameraChannel, true);}}else{if (!bDetected){SetNightMode(uiCameraChannel, true);SwitchWhiteLight(uiCameraChannel, false);}}}m_mutexWork.Unlock();return 0;
}unsigned int CISP::Run()
{while (!m_bStop){m_mutexWork.Lock();for (unsigned int i = 0; i < m_vctWorkInfo.size(); i++){TIspCameraWorkInfo &cwInfo = m_vctWorkInfo[i];TMppIspCameraParam &cp = m_param.vctCamera[i];if (cwInfo.mode != MppNightVisionMode_BlackWhiteOn && cwInfo.mode != MppNightVisionMode_BlackWhiteOff){if (cp.detectMode == MppDayNightDetectMode_ADC){Work_ADC(i, cp, cwInfo);}else if (cp.detectMode == MppDayNightDetectMode_GPIO){Work_GPIO(i, cp, cwInfo);}else{Work_Soft(i, cp, cwInfo);}}}m_mutexWork.Unlock();CHP_BaseThread::Sleep(1000, 10);}return 0;
}void CISP::Work_ADC(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo)
{CAdcAux *pAdc = (CAdcAux *)cwInfo.adc.pAdc;if (!cwInfo.adc.bOpened){int nRet = pAdc->Open(uiCameraChannel);if (nRet == 0){pAdc->Enable();cwInfo.adc.bOpened = true;}else{cwInfo.adc.uiOpenTryCount++;if (cwInfo.adc.uiOpenTryCount % 10 == 0){CHP_Logger::Error(m_param.pLogger, "isp adc open failed: %d", nRet);}}}else{bool bNight = false;int nValue = 0;int nRet = pAdc->GetValue(nValue);if (nRet == 0){if (nValue < cp.adcInfo.nSwitchToNightAdc){bNight = true;}else if (nValue > cp.adcInfo.nSwitchToDayAdc){bNight = false;}else{bNight = cwInfo.bNight;}#if falseTMppIspExposureAttr evAttr;TMppIspWBAttr wbAttr;m_pApi->Isp_GetExposureAttr(evAttr, uiCameraChannel);m_pApi->Isp_GetGlobalWhiteBalance(wbAttr, uiCameraChannel);unsigned int uiGbGain = (wbAttr.usBlueGain != 0) ? (65536 / wbAttr.usBlueGain) : wbAttr.usBlueGain;CHP_Logger::Trace(m_param.pLogger, "adc value: %d, %u, %u", nValue, evAttr.uiEv, uiGbGain);
#endif}SwitchDayNight(uiCameraChannel, bNight, cp, cwInfo);}
}void CISP::Work_GPIO(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo)
{bool bNight = false;bool bValue = false;int nRet = CHP_GPIOUtils::GetValue(cp.gpioInfo.uiDayNightDetectGpio, bValue);if (nRet == 0){bNight = cp.gpioInfo.bDayNightDetectGpioLowDay ? bValue : !bValue;}SwitchDayNight(uiCameraChannel, bNight, cp, cwInfo);
}void CISP::Work_Soft(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo)
{if (cwInfo.bNight){SwitchToDay(uiCameraChannel, cp, cwInfo);} else{TMppIspExposureAttr evAttr;int nRet = m_pApi->Isp_GetExposureAttr(evAttr, uiCameraChannel);bool bNight = nRet == 0 && evAttr.uiEv >= cp.softInfo.uiSwitchToNightEv;SwitchToNight(uiCameraChannel, cwInfo, bNight);}
}void CISP::SwitchDayNight(unsigned int uiCameraChannel, bool bNight, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo)
{if (cwInfo.bNight){SwitchToDay(uiCameraChannel, cp, cwInfo, &bNight);}else{SwitchToNight(uiCameraChannel, cwInfo, bNight);}
}void CISP::SwitchToNight(unsigned int uiCameraChannel, TIspCameraWorkInfo &cwInfo, bool bNight)
{if (bNight){cwInfo.uiNightCount++;if (cwInfo.uiNightCount > 5){cwInfo.bNight = true;cwInfo.uiDayCount = 0;cwInfo.soft.uiLastCheckTick = 0;cwInfo.soft.uiGbGainMin = 65536;cwInfo.soft.uiGbGainMax = 0;SetNightVisionMode_Impl(uiCameraChannel, cwInfo.mode, true);CHP_Logger::Info(m_param.pLogger, "isp switch to night");}}else{cwInfo.uiNightCount = 0;}
}void CISP::SwitchToDay(unsigned int uiCameraChannel, const TMppIspCameraParam &cp, TIspCameraWorkInfo &cwInfo, bool *pbNight /* = NULL */)
{TMppIspExposureAttr evAttr;int nRet = m_pApi->Isp_GetExposureAttr(evAttr, uiCameraChannel);TMppIspWBAttr wbAttr;int nRet2 = m_pApi->Isp_GetGlobalWhiteBalance(wbAttr, uiCameraChannel);if (nRet != 0 || nRet2 != 0){return;}unsigned int uiCurTick = CHP_Utils::GetCurTick();if (cwInfo.soft.uiLastCheckTick == 0 || uiCurTick - cwInfo.soft.uiLastCheckTick >= 3 * 1000){GetGainThreshold(uiCameraChannel, cwInfo.soft.uiGbGainMin, cwInfo.soft.uiGbGainMax);cwInfo.soft.uiLastCheckTick = uiCurTick;}if (evAttr.uiEv <= cp.softInfo.uiSwitchToDayEv){bool bOpenForEver = false;bool bTwinkle = false;bool bIsOn = false;if (m_param.pCbGetWhiteLightStatus != NULL){m_param.pCbGetWhiteLightStatus(uiCameraChannel, bOpenForEver, bIsOn, bTwinkle, m_param.pCbContext);}bool bMaybeDay = false;unsigned int uiGbGain = (wbAttr.usBlueGain != 0) ? (65536 / wbAttr.usBlueGain) : wbAttr.usBlueGain;if (bOpenForEver){if (!bTwinkle){bMaybeDay = uiGbGain + cp.softInfo.uiBlueGainDiffBetweenCurAndMax < cwInfo.soft.uiGbGainMax;}}else{if (!bTwinkle && !bIsOn){if (pbNight == NULL){bMaybeDay = uiGbGain > cwInfo.soft.uiGbGainMin + cp.softInfo.uiBlueGainDiffBetweenCurAndMin;}else{bMaybeDay = !(*pbNight);}}}if (bMaybeDay){cwInfo.uiDayCount++;if (cwInfo.uiDayCount > 5){cwInfo.bNight = false;cwInfo.uiNightCount = 0;SetNightVisionMode_Impl(uiCameraChannel, cwInfo.mode, false);CHP_Logger::Info(m_param.pLogger, "isp switch to day, %u, %u, %u, %d, %d, %d", uiGbGain, cwInfo.soft.uiGbGainMin, cwInfo.soft.uiGbGainMax, bOpenForEver, bTwinkle, bIsOn);}}else{cwInfo.uiDayCount = 0;}}else{cwInfo.uiDayCount = 0;}   
}void CISP::SetIrNight(unsigned int uiCameraChannel, bool bNight)
{SetIrFilter(uiCameraChannel, bNight);SetIrLight(uiCameraChannel, bNight);
}void CISP::SetNightMode(unsigned int uiCameraChannel, bool bNight)
{SetIrNight(uiCameraChannel, bNight);m_pApi->Isp_SetRunningMode(bNight, uiCameraChannel);
}void CISP::SwitchWhiteLight(unsigned int uiCameraChannel, bool bOn)
{if (m_param.pCbSwitchWhiteLight != NULL){m_param.pCbSwitchWhiteLight(uiCameraChannel, bOn, m_param.pCbContext);}
}void CISP::SetNightVisionMode_Impl(unsigned int uiCameraChannel, IMppNightVisionMode mode, bool bNight)
{if (mode == MppNightVisionMode_BlackWhiteOff || mode == MppNightVisionMode_BlackWhiteOn){bNight = mode == MppNightVisionMode_BlackWhiteOn;SetNightMode(uiCameraChannel, bNight);SwitchWhiteLight(uiCameraChannel, false);        }else if (mode == MppNightVisionMode_BlackWhiteAuto){SetNightMode(uiCameraChannel, bNight);SwitchWhiteLight(uiCameraChannel, false);        }else if (mode == MppNightVisionMode_FullColor){SetNightMode(uiCameraChannel, false);SwitchWhiteLight(uiCameraChannel, true);}else{SetNightMode(uiCameraChannel, bNight);SwitchWhiteLight(uiCameraChannel, false);}
}void CISP::GetGainThreshold(unsigned int uiCameraChannel, unsigned int &uiMin, unsigned int &uiMax)
{TMppIspWBAttr wbAttr;int nRet = m_pApi->Isp_GetGlobalWhiteBalance(wbAttr, uiCameraChannel);if (nRet == 0){unsigned int uiGbGain = (wbAttr.usBlueGain != 0) ? (65536 / wbAttr.usBlueGain) : wbAttr.usBlueGain;uiMin = (uiMin > uiGbGain) ? uiGbGain : uiMin;uiMax = (uiMax < uiGbGain) ? uiGbGain : uiMax;}
}

        在Init接口中,我们对传入的参数进行了合法性校验,初始化了红外滤光片、红外灯的GPIO管脚,并根据不同的日夜探测模式进行了不同的逻辑处理。

        在线程Run函数中,我们根据不同的日夜视觉模式和日夜探测模式,分别调用了Work_ADC、Work_GPIO、Work_Soft三个不同的函数进行处理。

        在Work_ADC函数中,会先打开ADC,然后读取ADC的值,并将值与nSwitchToNightAdc、nSwitchToDayAdc进行比较,以判断当前是白天还是夜晚。注意:这里的判断只是一个参考值,所以,还需要调用SwitchDayNight函数,通过软光敏的辅助来进一步判断。

        在Work_GPIO函数中,直接读取GPIO管脚的值,并结合bDayNightDetectGpioLowDay,即可判断当前是白天还是夜晚。后续也需要借助SwitchDayNight函数,通过软光敏的辅助来进一步判断。

        在Work_Soft函数中,会调用SwitchToDay、SwitchToNight函数来判断是否需要切换到白天和夜晚。

        君正ISP的封装就介绍到这里了,下一节,我们介绍君正视频采集的封装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/18501.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Docker Desktop 安装 Centos 系统

一、前言 由于 Docker 是一个容器&#xff0c;它支持在一个服务器进行多服务部署&#xff0c;并且还能保持服务的独立性&#xff0c;那么&#xff0c;在Docker 上的运用时 我们也是可以 独立部署多个系统来做不同是其他&#xff0c;这样环境独立的情况下&#xff0c;也就不会造…

数字美容的艺术:深入探讨面部美化算法和人脸美型SDK

在当今社交媒体和自拍热潮的背景下&#xff0c;数字美容成为了许多人追求面部完美外貌的选择。通过面部美化算法和人脸美型SDK&#xff0c;人们可以在瞬间实现肌肤光滑、五官精致的效果。然而&#xff0c;这种技术的背后隐藏着怎样的原理和技术手段&#xff1f;本文将深入探讨面…

开源LLM大模型微调简明教程

我相信你们大多数人都听说过 ChatGPT 并尝试过它来回答你的问题&#xff01; 有没有想过幕后发生了什么&#xff1f; 它由 Open AI 开发的大型语言模型 GPT-3 提供支持。 这些大型语言模型&#xff08;通常称为LLM&#xff09;开启了自然语言处理的许多可能性。 推荐&#xff1…

Android 圆环统计图(带外延折线可点击)

需求先看UI效果图吧 看到这肯定去找轮子&#xff0c;找了半天&#xff0c;没找到相似的&#xff0c;大部分搜到的都是点击外凸&#xff0c;而这个UI是内凸&#xff0c;其实外凸内凸区别还不小&#xff0c;没找到一样的&#xff0c;于是乎&#xff0c;和iOS说好了要不就放弃吧&…

2023年大语言模型神器 - LangChain

概要 今天介绍一下 LangChain 框架&#xff0c;LangChain 是一个帮助在应用程序中使用大型语言模型&#xff08;LLM&#xff09;的编程框架。它可以将大型语言模型与其他计算或知识来源相结合&#xff0c;从而实现功能更加强大的应用。 最初 LangChain 是一个开源项目&#xf…

open3d实现搜索在一个球内部的点云

目录 写在前面原理代码结果参考完 写在前面 1、本文内容 给定一个点云P和一个圆心为center&#xff0c;半径为r的球&#xff0c;搜索出P中属于球内的点 2、平台/环境 使用open3d, cmake&#xff0c;适用windows/linux 3、转载请注明出处&#xff1a; https://blog.csdn.net/q…

【uniapp开发小程序】实现同声传译(长按语音转文字)

效果图&#xff1a; 插件&#xff1a; 采用小程序插件&#xff1a;微信同声传译。插件文档定位 具体步骤&#xff1a; 先登录小程序后台&#xff08;项目别错了&#xff09;&#xff1a;官网传送然后 设置 > 第三方设置 > 添加插件 在插件文档里面拿到Appid和版本号 在…

14-Vue插槽(slot),制作可复用组件

什么是 slot ? Vue 将 <slot>元素作为承载分发内容的出口。插槽内可以包含任何模板代码&#xff0c;包括 HTML或其它组件。 在某些组件的模板中&#xff0c;有一部分区域需要父组件来指定 <!-- message组件&#xff1a;一个弹窗消息 --> <div class"mes…

组合取球-2022年全国青少年信息素养大赛Python国赛第6题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第8讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计…

安全防御 --- DDOS攻击(01)

DOS攻击&#xff08;deny of service&#xff09;--- 拒绝式服务攻击 例&#xff1a;2016年10月21日&#xff0c;美国提供动态DNS服务的DynDNS遭到DDOS攻击&#xff0c;攻击导致许多使用DynDNS服务的网站遭遇访问问题&#xff0c;此事件中&#xff0c;黑客人就是运用了DNS洪水…

LinearAlgebraMIT_5_SpacesOfVectors

这一节中我们将学习向量空间。 x.1 转置矩阵和构造对称矩阵 在开启向量空间的学习前我们先复习一下转置矩阵和置换矩阵。我们将矩阵转置前后不变的矩阵称为对称矩阵。而我们如何得到一个对称矩阵呢&#xff0c;我们使用矩阵乘以矩阵的转置便可得到。 x.2 Vectors Space 向量…

如何执行Photoshop脚本

环境 Photoshop: CC2017 OS: Windows 10 脚本放置位置 C:\Program Files\Adobe\Adobe Photoshop CC 2015\Presets\Scripts #也就是 PS的安装目录\Presets\Scripts