解压缩和显示Canon EDSDK实时视图时出现问题

时间:2019-03-07 21:35:16

标签: c++ opencv video edsdk libjpeg-turbo

嗨,我正在尝试使用EDSDK从佳能相机显示实时取景。我设法使其工作了一些,但出现了一些奇怪的伪像。它是黑色和灰色,太小了,图像是...两倍?。

我从 tjDecompressHeader3() EdsImageInfo()获得的有关分辨率的信息均为1056 x 704。但是,相机实时取景中的许多图像并未像其外部那样在PC上显示。 感觉就是这样:https://imgur.com/a/1DW6ThO

是什么原因造成的?要小缓冲区?分辨率错误?我迷路了。

在这里,我正在屏幕上拍摄代码编辑器: https://i.gyazo.com/27dc0503ee23734ce571928f3a179d77.mp4

编辑:所以好吧,我尝试在tjDecompress函数中将TJPF_RGB更改为TJPF_GRAY,它可以正常工作,但除了黑色和白色外,效果都很好。 (我尝试了所有像素格式)。

这是此项目的相关代码。 (这是我编写的第一个C ++代码,对不起)。

LVERROR LiveView::decompress(unsigned long strLen, unsigned char* strPtr, unsigned char** decompressed)
{
    LVERROR d_err = LV_ERR_OK;
    char* d_err_str = NULL;

    unsigned char* dstBuf = NULL;
    unsigned long buffSize;
    int width, height, jpegSubsamp, jpegColorspace;


    tjhandle _jpegDecompressorHandle = tjInitDecompress();

    if (_jpegDecompressorHandle == NULL)
    {
        d_err_str = tjGetErrorStr();
        d_err = LV_ERR_CREATING_DECOMPRESSION_HANDLE;
    }

    if (d_err == LV_ERR_OK)
    {
        d_err = tjDecompressHeader3(
            _jpegDecompressorHandle,
            strPtr,
            strLen,
            &width,
            &height,
            &jpegSubsamp,
            &jpegColorspace); 

        if (d_err != LV_ERR_OK)
        {
            d_err_str = tjGetErrorStr();
            d_err = LV_ERR_DECOMPRESS_HEADER;
        }
        std::cout << width << " x " << height << std::endl; // 1056 x 704
    }

    if (d_err == LV_ERR_OK)
    {
        buffSize = tjBufSize(width, height, jpegSubsamp);
        if (buffSize < 0)
        {
            d_err_str = tjGetErrorStr();
            d_err = LV_ERR_BUFSIZE_OUT_OF_BOUNDS;
        }
    }

    if (d_err == LV_ERR_OK)
    {
        dstBuf = tjAlloc(buffSize);

        d_err = tjDecompress2(
            _jpegDecompressorHandle,
            strPtr,
            strLen,
            dstBuf,
            width,
            0,
            height,
            TJPF_RGB,
            TJFLAG_FASTDCT);

        if (d_err != LV_ERR_OK)
        {
            d_err_str = tjGetErrorStr();
            d_err = LV_ERR_DECOMPRESS2;
        }
    }

    if (d_err == LV_ERR_OK)
        *decompressed = *&dstBuf;
    else
        std::cout << "err: " << d_err_str << std::endl;

    return d_err;   
}

//... ...

void LiveView::displayImage(cv::Mat image)
{
    cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
    cv::imshow(windowName, image);  
}

//... ...

cv::Mat LiveView::createImageMat(int height, int width, unsigned char* buffer)
{
    cv::Mat image = cv::Mat(height, width, CV_8UC1, buffer);
    return image;
}

//... ...

void LiveView::liveLoop(Canon canon)
{
    LVERROR  lv_err  = LV_ERR_OK;
    EdsError eds_err = EDS_ERR_OK;

    unsigned char* decompressed = NULL;
    EdsImageInfo imageInfo;

    while (true)
    {
        eds_err = canon.downloadImageData();

        if (eds_err != EDS_ERR_OK)
            throw eds_err;

        if (canon.gotNewFrame())
        {
            canon.getImageInfo(canon.getStreamRef(), imageInfo);

            lv_err = decompress(canon.getStreamLength(), (unsigned char*)canon.getStreamPointer(), &decompressed);
            if (lv_err != LV_ERR_OK)
                throw(lv_err);

            std::cout << imageInfo.width << " x " << imageInfo.height << std::endl; // 1056 x 704

            cv::Mat image = createImageMat(imageInfo.height, imageInfo.width, decompressed);
            displayImage(image);
            tick();

            tjFree(decompressed);
        }
    }
}

0 个答案:

没有答案