libcamera parameter issue



  • Hallo,

    aus widrigen Gründen muss ich in meinen Webserver das libcamera Interface als Ersatz für das mmal lib von Brodcom integrieren.

    Dabei stieß ich auf schwere Probleme / Fehler bezüglich der gültigen Parameter Ranges für die Kamera wie saturation,gain,exposure,sharpness usw..

    Ich erlange die Ranges nach dem verbinden der Kamera mit den buffers:

    void CCamSrv::CameraRanges(void)
    {
        libcamera::ControlInfoMap controls(m_Camera->controls());
        libcamera::ControlInfoMap::iterator ctrl;
    
        ctrl = controls.find(&libcamera::controls::ExposureTime);
        m_DurMin = ctrl->second.min().get<int32_t>();
        m_DurMax = ctrl->second.max().get<int32_t>();
      
            ctrl = controls.find(&libcamera::controls::Saturation);
        m_SatMin = 0;// ctrl->second.min().get<float>() / 10.0f;
        m_SatMax = 1;// ctrl->second.max().get<float>() / 10.0f;
      
            ctrl = controls.find(&libcamera::controls::Brightness);
        m_BriMin = 0;// ctrl->second.min().get<float>() / 10.0f;
        m_BriMax = 0.5;// ctrl->second.max().get<float>() / 10.0f;
       
            ctrl = controls.find(&libcamera::controls::Contrast);
        m_ConMin = 0.1;// ctrl->second.min().get<float>() / 10.0f;
        m_ConMax = 1.5;// ctrl->second.max().get<float>() / 10.0f;
      
            ctrl = controls.find(&libcamera::controls::Sharpness);
        m_ShaMin = 0;// ctrl->second.min().get<float>() / 10.0f;
        m_SahMax = 32;// ctrl->second.max().get<float>() / 10.0f;
      
            ctrl = controls.find(&libcamera::controls::ExposureValue);
        m_ExpMin = ctrl->second.min().get<float>() ;
        m_ExpMax = ctrl->second.max().get<float>()/10.0f ;
    
            ctrl = controls.find(&libcamera::controls::AnalogueGain);
        m_AnlMin = 0.1;//ctrl->second.min().get<float>() / 10.0f;
        m_AnlMax = 2;// ctrl->second.max().get<float>() / 10.0f;
    }
    

    Wie man sieht musste ich alle Parameter händisch anpassen, damit keine völlige Übersteuerung der Kamera statt findet. Diese Ranges die ich erhalte sind alle samt nicht auf die Kamera übertragbar bezüglich Min/Max

    Die Parameter selber erlange ich über eine Webseite wo der User 100% Slider betätigen kann, diese transformiere ich bei der Benutzereingabe auf den Physikalischen Range der Kamera :

    bool CCamSrv::SetParameter(std::string name, std::string value) //lua command interface offline by the fuck 
    {
        if (name.empty() || value.empty())
            return false;
    
        float fval(atof(value.c_str())); //printf("%s=%0.3f CamTi=%ld\n", name.c_str(), fval, m_lastti);
        if ((int)name.find("Saturation") > -1)
        {
            m_fSaturation = m_SatMin + (fval * ((m_SatMax-m_SatMin) / 100.0)), m_bParamChg = true;
        }else if ((int)name.find("Brightness") > -1)
        {
            m_fBrightness = m_BriMin + (fval * ((m_BriMax - m_BriMin) / 100.0f)), m_bParamChg = true;
        }else if ((int)name.find("Contrast") > -1)
        {
            m_fContrast = m_ConMin + (fval * ((m_ConMax - m_ConMin) / 100.0f)), m_bParamChg = true;
        }else if ((int)name.find("Sharpness") > -1)
        {
            m_fSharpness = m_ShaMin + (fval * ((m_SahMax - m_ShaMin) / 100.0f)), m_bParamChg = true;
        }else if ((int)name.find("Quality") > -1)
        {
            m_Quality = (unsigned int) fval;
        }else if ((int)name.find("Exposure") > -1)
        {
            m_fExposure = m_ExpMin + (fval * ((m_ExpMax - m_ExpMin) / 100.0f)), m_bParamChg = true;
        }else if ((int)name.find("Gain") > -1)
        {
            m_fGain = m_AnlMin + (fval * ((m_AnlMax - m_AnlMin) / 100.0f)), m_bParamChg = true;
        }else if ((int)name.find("Duration") > -1)
        {
            m_Duration = m_DurMin + (fval * ((m_DurMax - m_DurMin) / 100.0f)), m_bParamChg = true;
        }else if ((int)name.find("Play") > -1)
        {
            Start();
        }else if ((int)name.find("Hold") > -1)
        {
            Stop();
        }else return false;
    
        return true;
    }
    

    In der callback Funktion von LibCamera hat man die Möglichkeit an einer Stelle die neuen Werte an die Kamera zu übertragen funktioniert auch soweit :

    void CCamSrv::RequestCompleted(libcamera::Request* request)//wtf without *userdata
    {
        if (request->status() == libcamera::Request::RequestCancelled || !g_pHost->m_bIsRunning)
        {
            vcos_semaphore_post(&g_pHost->m_semaframe);
            return;
        }
    
        vcos_mutex_lock(&g_pHost->m_FrameLatch);
    
        const libcamera::Request::BufferMap& buffers = request->buffers();
        for (libcamera::Request::BufferMap::const_iterator it = buffers.begin(); it != buffers.end(); it++)
        {
            libcamera::FrameBuffer* buffer = (*it).second;
            const libcamera::FrameMetadata& metadata = buffer->metadata();
          
            unsigned int nplane(0);  //metadata.timestamp
            for (const libcamera::FrameMetadata::Plane& plane : metadata.planes())//after control its calling once only
                memcpy((g_pHost->m_pMem[((g_pHost->m_PicNr + 1) % NUMBUFFS)] + sizeof(BITMAPFILEHEADER)) + sizeof(BITMAPINFOHEADER), g_pHost->m_MapBuffMem.find(buffer)->second, metadata.planes()[nplane++].bytesused);
        }
    
        g_pHost->m_PicNr++;
        vcos_mutex_unlock(&g_pHost->m_FrameLatch);
      
        request->reuse(libcamera::Request::ReuseBuffers);
    
        if (g_pHost->m_bParamChg)
        {
            g_pHost->m_bParamChg = false;
            libcamera::ControlList& controls(request->controls());
            controls.set<float>(libcamera::controls::Saturation, g_pHost->m_fSaturation);
            controls.set<float>(libcamera::controls::Brightness, g_pHost->m_fBrightness);
            controls.set<float>(libcamera::controls::Contrast, g_pHost->m_fContrast);
            controls.set<float>(libcamera::controls::Sharpness, g_pHost->m_fSharpness);
            controls.set<float>(libcamera::controls::ExposureValue, g_pHost->m_fExposure);
            controls.set<float>(libcamera::controls::AnalogueGain, g_pHost->m_fGain);
            //controls.set<int32_t>(libcamera::controls::ExposureTime,  (int32_t)g_pHost->m_Duration);
            //controls.set<int32_t>(libcamera::controls::AeExposureMode, libcamera::controls::AeExposureModeEnum::ExposureNormal);
        }
    
        g_pHost->m_Camera->queueRequest(request);
    }
    

    Die Frage ist nun, warum erhalte ich falsche Ranges von dem Interface ? Ich habe dazu sogar ein Video her gelitten :

    https://youtu.be/vMh48QhnAgY

    Die Frage ist wer hat schon Erfahrungen mit dem Parameter setup von libcamera (a pain deep in the ass)

    Danke für Hinweise

    Karsten aus Berlin


Anmelden zum Antworten