WinRT C++(Win10),opencv HSV颜色空间,图像显示,伪影

本文关键字:颜色 色空间 图像 伪影 显示 HSV opencv C++ Win10 WinRT | 更新日期: 2023-09-27 18:26:24

我的目标是进行对象跟踪。

我有一个UWP c#应用程序和链接的c++windows运行时组件。在那里我可以获得opencv的访问权限。

  • 在c#中,MediaCapture返回SoftwareBitmap
  • 然后我将SoftwareBitmap传递给c++,并将其转换为opencv的Mat
  • 然后cvtColor(cvFrame, cvFrame, COLOR_BGR2HSV);
  • 然后使用BitmapPixelFormat::Bgra8(软件位图只接受Bgra8)和BitmapAlphaMode::Ignore转换回SoftwareBitmap

这是我的屏幕

如果我跳过一个cvtColor部分,只转换为cv::Mat并返回到SoftwareBitmap,我会得到一个很好的图像。。。

我知道图像的频道有问题。。。但我不知道该去哪里挖了。我认为cvtColor之后的cv::Mat是正确的。。。但我希望看到图片创作的中间步骤。(HSV,阈值,然后结果)

如有任何建议,我们将不胜感激。

PS我尝试过imwrite,但没有创建任何文件。

更新的转换

Mat Convert(SoftwareBitmap^ from)
{
    BitmapBuffer^ bmpBuffer = from->LockBuffer(BitmapBufferAccessMode::ReadWrite);
    unsigned char* pPixels = GetPointerToPixelData(bmpBuffer->CreateReference());
    Mat mat(from->PixelHeight, from->PixelWidth, CV_8UC4);
    memcpy(mat.data, pPixels, 4 * from->PixelHeight * from->PixelWidth);
    return mat;
}
SoftwareBitmap^ Convert(Mat from)
{
    SoftwareBitmap^ sBitmap = ref new SoftwareBitmap(BitmapPixelFormat::Bgra8, from.cols, from.rows, BitmapAlphaMode::Ignore);
    BitmapBuffer^ bmpBuffer = sBitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite);
    auto reference = bmpBuffer->CreateReference();
    unsigned char* dstPixels = GetPointerToPixelData(reference);
    memcpy(dstPixels, from.data, from.step.buf[1] * from.cols*from.rows);
    return sBitmap;
}
unsigned char* GetPointerToPixelData(IBuffer^ buffer)
{
    ComPtr<IBufferByteAccess> bufferByteAccess;
    ComPtr<IInspectable> insp((IInspectable*)buffer);
    ThrowIfFailed(insp.As(&bufferByteAccess));
    unsigned char* pixels = nullptr;
    ThrowIfFailed(bufferByteAccess->Buffer(&pixels));
    return pixels;
}
unsigned char* GetPointerToPixelData(IMemoryBufferReference^ reference)
{
    ComPtr<IMemoryBufferByteAccess> bufferByteAccess;
    ThrowIfFailed(reinterpret_cast<IInspectable*>(reference)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess)));
    unsigned char* pixels = nullptr;
    unsigned int capacity = 0;
    ThrowIfFailed(bufferByteAccess->GetBuffer(&pixels, &capacity));
    return pixels;
}

WinRT C++(Win10),opencv HSV颜色空间,图像显示,伪影

由于您没有发布从软件位图/cv::Mat进行实际转换的代码。

我的最佳猜测是,3通道图像数据显示为好像有4个通道。

好的,我找到了解决方案。

//convert from SoftwareBitmap to Mat
Mat cvFrame = this->Convert(frame);
//change color space
cvtColor(cvFrame, cvFrame, COLOR_BGR2HSV);
// split chanels
vector<Mat> hsvChannels(3);
split(cvFrame, hsvChannels);
//create empty chanel
Mat empty;
empty = Mat::zeros(cvFrame.rows, cvFrame.cols, CV_8UC1);
// create hsv with empty alpha
vector<Mat> channels;
channels.push_back(hsvChannels[0]); //h
channels.push_back(hsvChannels[1]); //s
channels.push_back(hsvChannels[2]); //v
channels.push_back(empty); //a
//put back to Mat
merge(channels, cvFrame);
// convert back to SoftwareBitmap 
return this->Convert(cvFrame);