嗨,我正在尝试使用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);
}
}
}