root/modules/videoio/src/cap_intelperc.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. m_timeStampStartNS
  2. isValid
  3. grabFrame
  4. getProfileIDX
  5. getProperty
  6. setProperty
  7. initDevice
  8. initStreamImpl
  9. validProfile
  10. enumProfiles
  11. initStream
  12. getProperty
  13. setProperty
  14. retrieveAsOutputArray
  15. initStream
  16. getProperty
  17. setProperty
  18. retrieveDepthAsOutputArray
  19. retrieveIRAsOutputArray
  20. retrieveUVAsOutputArray
  21. validProfile
  22. retriveFrame
  23. getProperty
  24. setProperty
  25. grabFrame
  26. retrieveFrame
  27. getCaptureDomain
  28. isOpened

#ifdef HAVE_INTELPERC

#include "cap_intelperc.hpp"

namespace cv
{

///////////////// IntelPerCStreamBase //////////////////

IntelPerCStreamBase::IntelPerCStreamBase()
    : m_profileIdx(-1)
    , m_frameIdx(0)
    , m_timeStampStartNS(0)
{
}
IntelPerCStreamBase::~IntelPerCStreamBase()
{
}

bool IntelPerCStreamBase::isValid()
{
    return (m_device.IsValid() && m_stream.IsValid());
}
bool IntelPerCStreamBase::grabFrame()
{
    if (!m_stream.IsValid())
        return false;
    if (-1 == m_profileIdx)
    {
        if (!setProperty(CV_CAP_PROP_INTELPERC_PROFILE_IDX, 0))
            return false;
    }
    PXCSmartSP sp;
    m_pxcImage.ReleaseRef();
    if (PXC_STATUS_NO_ERROR > m_stream->ReadStreamAsync(&m_pxcImage, &sp))
        return false;
    if (PXC_STATUS_NO_ERROR > sp->Synchronize())
        return false;
    if (0 == m_timeStampStartNS)
        m_timeStampStartNS = m_pxcImage->QueryTimeStamp();
    m_timeStamp = (double)((m_pxcImage->QueryTimeStamp() - m_timeStampStartNS) / 10000);
    m_frameIdx++;
    return true;
}
int IntelPerCStreamBase::getProfileIDX() const
{
    return m_profileIdx;
}
double IntelPerCStreamBase::getProperty(int propIdx) const
{
    double ret = 0.0;
    switch (propIdx)
    {
    case CV_CAP_PROP_INTELPERC_PROFILE_COUNT:
        ret = (double)m_profiles.size();
        break;
    case CV_CAP_PROP_FRAME_WIDTH :
        if ((0 <= m_profileIdx) && (m_profileIdx < m_profiles.size()))
            ret = (double)m_profiles[m_profileIdx].imageInfo.width;
        break;
    case CV_CAP_PROP_FRAME_HEIGHT :
        if ((0 <= m_profileIdx) && (m_profileIdx < m_profiles.size()))
            ret = (double)m_profiles[m_profileIdx].imageInfo.height;
        break;
    case CV_CAP_PROP_FPS :
        if ((0 <= m_profileIdx) && (m_profileIdx < m_profiles.size()))
        {
            ret = ((double)m_profiles[m_profileIdx].frameRateMin.numerator / (double)m_profiles[m_profileIdx].frameRateMin.denominator
                    + (double)m_profiles[m_profileIdx].frameRateMax.numerator / (double)m_profiles[m_profileIdx].frameRateMax.denominator) / 2.0;
        }
        break;
    case CV_CAP_PROP_POS_FRAMES:
        ret  = (double)m_frameIdx;
        break;
    case CV_CAP_PROP_POS_MSEC:
        ret  = m_timeStamp;
        break;
    };
    return ret;
}
bool IntelPerCStreamBase::setProperty(int propIdx, double propVal)
{
    bool isSet = false;
    switch (propIdx)
    {
    case CV_CAP_PROP_INTELPERC_PROFILE_IDX:
        {
            int propValInt = (int)propVal;
            if (0 > propValInt)
            {
                m_profileIdx = propValInt;
                isSet = true;
            }
            else if (propValInt < m_profiles.size())
            {
                if (m_profileIdx != propValInt)
                {
                    m_profileIdx = propValInt;
                    if (m_stream.IsValid())
                        m_stream->SetProfile(&m_profiles[m_profileIdx]);
                    m_frameIdx = 0;
                    m_timeStampStartNS = 0;
                }
                isSet = true;
            }
        }
        break;
    };
    return isSet;
}
bool IntelPerCStreamBase::initDevice(PXCSession *session)
{
    if (NULL == session)
        return false;

    pxcStatus sts = PXC_STATUS_NO_ERROR;
    PXCSession::ImplDesc templat;
    memset(&templat,0,sizeof(templat));
    templat.group   = PXCSession::IMPL_GROUP_SENSOR;
    templat.subgroup= PXCSession::IMPL_SUBGROUP_VIDEO_CAPTURE;

    for (int modidx = 0; PXC_STATUS_NO_ERROR <= sts; modidx++)
    {
        PXCSession::ImplDesc desc;
        sts = session->QueryImpl(&templat, modidx, &desc);
        if (PXC_STATUS_NO_ERROR > sts)
            break;

        PXCSmartPtr<PXCCapture> capture;
        sts = session->CreateImpl<PXCCapture>(&desc, &capture);
        if (!capture.IsValid())
            continue;

        /* enumerate devices */
        for (int devidx = 0; PXC_STATUS_NO_ERROR <= sts; devidx++)
        {
            PXCSmartPtr<PXCCapture::Device> device;
            sts = capture->CreateDevice(devidx, &device);
            if (PXC_STATUS_NO_ERROR <= sts)
            {
                m_device = device.ReleasePtr();
                return true;
            }
        }
    }
    return false;
}

void IntelPerCStreamBase::initStreamImpl(PXCImage::ImageType type)
{
    if (!m_device.IsValid())
        return;

    pxcStatus sts = PXC_STATUS_NO_ERROR;
    /* enumerate streams */
    for (int streamidx = 0; PXC_STATUS_NO_ERROR <= sts; streamidx++)
    {
        PXCCapture::Device::StreamInfo sinfo;
        sts = m_device->QueryStream(streamidx, &sinfo);
        if (PXC_STATUS_NO_ERROR > sts)
            break;
        if (PXCCapture::VideoStream::CUID != sinfo.cuid)
            continue;
        if (type != sinfo.imageType)
            continue;

        sts = m_device->CreateStream<PXCCapture::VideoStream>(streamidx, &m_stream);
        if (PXC_STATUS_NO_ERROR == sts)
            break;
        m_stream.ReleaseRef();
    }
}
bool IntelPerCStreamBase::validProfile(const PXCCapture::VideoStream::ProfileInfo& /*pinfo*/)
{
    return true;
}
void IntelPerCStreamBase::enumProfiles()
{
    m_profiles.clear();
    if (!m_stream.IsValid())
        return;
    pxcStatus sts = PXC_STATUS_NO_ERROR;
    for (int profidx = 0; PXC_STATUS_NO_ERROR <= sts; profidx++)
    {
        PXCCapture::VideoStream::ProfileInfo pinfo;
        sts = m_stream->QueryProfile(profidx, &pinfo);
        if (PXC_STATUS_NO_ERROR > sts)
            break;
        if (validProfile(pinfo))
            m_profiles.push_back(pinfo);
    }
}

///////////////// IntelPerCStreamImage //////////////////

IntelPerCStreamImage::IntelPerCStreamImage()
{
}
IntelPerCStreamImage::~IntelPerCStreamImage()
{
}

bool IntelPerCStreamImage::initStream(PXCSession *session)
{
    if (!initDevice(session))
        return false;
    initStreamImpl(PXCImage::IMAGE_TYPE_COLOR);
    if (!m_stream.IsValid())
        return false;
    enumProfiles();
    return true;
}
double IntelPerCStreamImage::getProperty(int propIdx) const
{
    switch (propIdx)
    {
    case CV_CAP_PROP_BRIGHTNESS:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_BRIGHTNESS, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_CONTRAST:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_CONTRAST, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_SATURATION:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_SATURATION, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_HUE:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_HUE, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_GAMMA:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_GAMMA, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_SHARPNESS:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_SHARPNESS, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_GAIN:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_GAIN, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_BACKLIGHT:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_BACK_LIGHT_COMPENSATION, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_EXPOSURE:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_EXPOSURE, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    //Add image stream specific properties
    }
    return IntelPerCStreamBase::getProperty(propIdx);
}
bool IntelPerCStreamImage::setProperty(int propIdx, double propVal)
{
    switch (propIdx)
    {
    case CV_CAP_PROP_BRIGHTNESS:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_BRIGHTNESS, (float)propVal));
        }
        break;
    case CV_CAP_PROP_CONTRAST:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_CONTRAST, (float)propVal));
        }
        break;
    case CV_CAP_PROP_SATURATION:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_SATURATION, (float)propVal));
        }
        break;
    case CV_CAP_PROP_HUE:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_HUE, (float)propVal));
        }
        break;
    case CV_CAP_PROP_GAMMA:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_GAMMA, (float)propVal));
        }
        break;
    case CV_CAP_PROP_SHARPNESS:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_SHARPNESS, (float)propVal));
        }
        break;
    case CV_CAP_PROP_GAIN:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_GAIN, (float)propVal));
        }
        break;
    case CV_CAP_PROP_BACKLIGHT:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_BACK_LIGHT_COMPENSATION, (float)propVal));
        }
        break;
    case CV_CAP_PROP_EXPOSURE:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_EXPOSURE, (float)propVal));
        }
        break;
    //Add image stream specific properties
    }
    return IntelPerCStreamBase::setProperty(propIdx, propVal);
}
bool IntelPerCStreamImage::retrieveAsOutputArray(cv::OutputArray image)
{
    if (!m_pxcImage.IsValid())
        return false;
    PXCImage::ImageInfo info;
    m_pxcImage->QueryInfo(&info);

    PXCImage::ImageData data;
    m_pxcImage->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::COLOR_FORMAT_RGB24, &data);

    if (PXCImage::SURFACE_TYPE_SYSTEM_MEMORY != data.type)
        return false;

    cv::Mat temp(info.height, info.width, CV_8UC3, data.planes[0], data.pitches[0]);
    temp.copyTo(image);

    m_pxcImage->ReleaseAccess(&data);
    return true;
}

///////////////// IntelPerCStreamDepth //////////////////

IntelPerCStreamDepth::IntelPerCStreamDepth()
{
}
IntelPerCStreamDepth::~IntelPerCStreamDepth()
{
}

bool IntelPerCStreamDepth::initStream(PXCSession *session)
{
    if (!initDevice(session))
        return false;
    initStreamImpl(PXCImage::IMAGE_TYPE_DEPTH);
    if (!m_stream.IsValid())
        return false;
    enumProfiles();
    return true;
}
double IntelPerCStreamDepth::getProperty(int propIdx) const
{
    switch (propIdx)
    {
    case CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_LOW_CONFIDENCE_VALUE, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_SATURATION_VALUE, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD:
        {
            if (!m_device.IsValid())
                return 0.0;
            float fret = 0.0f;
            if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_CONFIDENCE_THRESHOLD, &fret))
                return (double)fret;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ:
        {
            if (!m_device.IsValid())
                return 0.0f;
            PXCPointF32 ptf;
            if (PXC_STATUS_NO_ERROR == m_device->QueryPropertyAsPoint(PXCCapture::Device::PROPERTY_DEPTH_FOCAL_LENGTH, &ptf))
                return (double)ptf.x;
            return 0.0;
        }
        break;
    case CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT:
        {
            if (!m_device.IsValid())
                return 0.0f;
            PXCPointF32 ptf;
            if (PXC_STATUS_NO_ERROR == m_device->QueryPropertyAsPoint(PXCCapture::Device::PROPERTY_DEPTH_FOCAL_LENGTH, &ptf))
                return (double)ptf.y;
            return 0.0;
        }
        break;
        //Add depth stream sepcific properties
    }
    return IntelPerCStreamBase::getProperty(propIdx);
}
bool IntelPerCStreamDepth::setProperty(int propIdx, double propVal)
{
    switch (propIdx)
    {
    case CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_LOW_CONFIDENCE_VALUE, (float)propVal));
        }
        break;
    case CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_SATURATION_VALUE, (float)propVal));
        }
        break;
    case CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD:
        {
            if (!m_device.IsValid())
                return false;
            return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_CONFIDENCE_THRESHOLD, (float)propVal));
        }
        break;
    //Add depth stream sepcific properties
    }
    return IntelPerCStreamBase::setProperty(propIdx, propVal);
}
bool IntelPerCStreamDepth::retrieveDepthAsOutputArray(cv::OutputArray image)
{
    return retriveFrame(CV_16SC1, 0, image);
}
bool IntelPerCStreamDepth::retrieveIRAsOutputArray(cv::OutputArray image)
{
    return retriveFrame(CV_16SC1, 1, image);
}
bool IntelPerCStreamDepth::retrieveUVAsOutputArray(cv::OutputArray image)
{
    return retriveFrame(CV_32FC2, 2, image);
}
bool IntelPerCStreamDepth::validProfile(const PXCCapture::VideoStream::ProfileInfo& pinfo)
{
    return (PXCImage::COLOR_FORMAT_DEPTH == pinfo.imageInfo.format);
}
bool IntelPerCStreamDepth::retriveFrame(int type, int planeIdx, cv::OutputArray frame)
{
    if (!m_pxcImage.IsValid())
        return false;
    PXCImage::ImageInfo info;
    m_pxcImage->QueryInfo(&info);

    PXCImage::ImageData data;
    m_pxcImage->AcquireAccess(PXCImage::ACCESS_READ, &data);

    if (PXCImage::SURFACE_TYPE_SYSTEM_MEMORY != data.type)
        return false;

    cv::Mat temp(info.height, info.width, type, data.planes[planeIdx], data.pitches[planeIdx]);
    temp.copyTo(frame);

    m_pxcImage->ReleaseAccess(&data);
    return true;
}

///////////////// VideoCapture_IntelPerC //////////////////

VideoCapture_IntelPerC::VideoCapture_IntelPerC()
    : m_contextOpened(false)
{
    pxcStatus sts = PXCSession_Create(&m_session);
    if (PXC_STATUS_NO_ERROR > sts)
        return;
    m_contextOpened = m_imageStream.initStream(m_session);
    m_contextOpened &= m_depthStream.initStream(m_session);
}
VideoCapture_IntelPerC::~VideoCapture_IntelPerC(){}

double VideoCapture_IntelPerC::getProperty(int propIdx) const
{
    double propValue = 0;
    int purePropIdx = propIdx & ~CV_CAP_INTELPERC_GENERATORS_MASK;
    if (CV_CAP_INTELPERC_IMAGE_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
    {
        propValue = m_imageStream.getProperty(purePropIdx);
    }
    else if (CV_CAP_INTELPERC_DEPTH_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
    {
        propValue = m_depthStream.getProperty(purePropIdx);
    }
    else
    {
        propValue = m_depthStream.getProperty(purePropIdx);
    }
    return propValue;
}
bool VideoCapture_IntelPerC::setProperty(int propIdx, double propVal)
{
    bool isSet = false;
    int purePropIdx = propIdx & ~CV_CAP_INTELPERC_GENERATORS_MASK;
    if (CV_CAP_INTELPERC_IMAGE_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
    {
        isSet = m_imageStream.setProperty(purePropIdx, propVal);
    }
    else if (CV_CAP_INTELPERC_DEPTH_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
    {
        isSet = m_depthStream.setProperty(purePropIdx, propVal);
    }
    else
    {
        isSet = m_depthStream.setProperty(purePropIdx, propVal);
    }
    return isSet;
}

bool VideoCapture_IntelPerC::grabFrame()
{
    if (!isOpened())
        return false;

    bool isGrabbed = false;
    if (m_depthStream.isValid())
        isGrabbed = m_depthStream.grabFrame();
    if ((m_imageStream.isValid()) && (-1 != m_imageStream.getProfileIDX()))
        isGrabbed &= m_imageStream.grabFrame();

    return isGrabbed;
}
bool VideoCapture_IntelPerC::retrieveFrame(int outputType, cv::OutputArray frame)
{
    switch (outputType)
    {
    case CV_CAP_INTELPERC_DEPTH_MAP:
        return m_depthStream.retrieveDepthAsOutputArray(frame);
    case CV_CAP_INTELPERC_UVDEPTH_MAP:
        return m_depthStream.retrieveUVAsOutputArray(frame);
    case CV_CAP_INTELPERC_IR_MAP:
        return m_depthStream.retrieveIRAsOutputArray(frame);
    case CV_CAP_INTELPERC_IMAGE:
        return m_imageStream.retrieveAsOutputArray(frame);
    }
    return false;
}
int VideoCapture_IntelPerC::getCaptureDomain()
{
    return CV_CAP_INTELPERC;
}

bool VideoCapture_IntelPerC::isOpened() const
{
    return m_contextOpened;
}

}

#endif //HAVE_INTELPERC

/* [<][>][^][v][top][bottom][index][help] */