From f3e666b7bbbb18bb580dae166f5f15c3a32e9558 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Wed, 7 Dec 2022 10:36:40 -0800 Subject: [PATCH] [cscore] Convert YUYV and UYVY directly to grayscale (#4777) This is significantly more efficient than converting by way of BGR. --- cscore/src/main/native/cpp/Frame.cpp | 65 +++++++++++++++++++++------- cscore/src/main/native/cpp/Frame.h | 2 + 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/cscore/src/main/native/cpp/Frame.cpp b/cscore/src/main/native/cpp/Frame.cpp index 881e82ec9a..e6f8e7c683 100644 --- a/cscore/src/main/native/cpp/Frame.cpp +++ b/cscore/src/main/native/cpp/Frame.cpp @@ -265,23 +265,12 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat, cur->pixelFormat == VideoMode::kGray) { return ConvertGrayToY16(cur); } - // If source is YUYV, UYVY, or RGB565, need to convert to BGR first + // If source is YUYV, UYVY, convert directly to Gray + // If RGB565, need to convert to BGR first if (cur->pixelFormat == VideoMode::kYUYV) { - // Check to see if BGR version already exists... - if (Image* newImage = - GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) { - cur = newImage; - } else { - cur = ConvertYUYVToBGR(cur); - } + cur = ConvertYUYVToGray(cur); } else if (cur->pixelFormat == VideoMode::kUYVY) { - // Check to see if BGR version already exists... - if (Image* newImage = - GetExistingImage(cur->width, cur->height, VideoMode::kBGR)) { - cur = newImage; - } else { - cur = ConvertUYVYToBGR(cur); - } + cur = ConvertUYVYToGray(cur); } else if (cur->pixelFormat == VideoMode::kRGB565) { // Check to see if BGR version already exists... if (Image* newImage = @@ -290,8 +279,8 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat, } else { cur = ConvertRGB565ToBGR(cur); } + cur = ConvertBGRToGray(cur); } - cur = ConvertBGRToGray(cur); if (pixelFormat == VideoMode::kY16) { cur = ConvertGrayToY16(cur); } @@ -407,6 +396,28 @@ Image* Frame::ConvertYUYVToBGR(Image* image) { return rv; } +Image* Frame::ConvertYUYVToGray(Image* image) { + if (!image || image->pixelFormat != VideoMode::kYUYV) { + return nullptr; + } + + // Allocate a grayscale image + auto newImage = + m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height, + image->width * image->height); + + // Convert + cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2GRAY_YUYV); + + // Save the result + Image* rv = newImage.release(); + if (m_impl) { + std::scoped_lock lock(m_impl->mutex); + m_impl->images.push_back(rv); + } + return rv; +} + Image* Frame::ConvertUYVYToBGR(Image* image) { if (!image || image->pixelFormat != VideoMode::kUYVY) { return nullptr; @@ -429,6 +440,28 @@ Image* Frame::ConvertUYVYToBGR(Image* image) { return rv; } +Image* Frame::ConvertUYVYToGray(Image* image) { + if (!image || image->pixelFormat != VideoMode::kUYVY) { + return nullptr; + } + + // Allocate a grayscale image + auto newImage = + m_impl->source.AllocImage(VideoMode::kGray, image->width, image->height, + image->width * image->height); + + // Convert + cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2GRAY_UYVY); + + // Save the result + Image* rv = newImage.release(); + if (m_impl) { + std::scoped_lock lock(m_impl->mutex); + m_impl->images.push_back(rv); + } + return rv; +} + Image* Frame::ConvertBGRToRGB565(Image* image) { if (!image || image->pixelFormat != VideoMode::kBGR) { return nullptr; diff --git a/cscore/src/main/native/cpp/Frame.h b/cscore/src/main/native/cpp/Frame.h index ab6170ff06..d5f537331e 100644 --- a/cscore/src/main/native/cpp/Frame.h +++ b/cscore/src/main/native/cpp/Frame.h @@ -195,7 +195,9 @@ class Frame { Image* ConvertMJPEGToBGR(Image* image); Image* ConvertMJPEGToGray(Image* image); Image* ConvertYUYVToBGR(Image* image); + Image* ConvertYUYVToGray(Image* image); Image* ConvertUYVYToBGR(Image* image); + Image* ConvertUYVYToGray(Image* image); Image* ConvertBGRToRGB565(Image* image); Image* ConvertRGB565ToBGR(Image* image); Image* ConvertBGRToGray(Image* image);