mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[cscore] Add UYVY image support (#4700)
This commit is contained in:
@@ -13,7 +13,8 @@ public class VideoMode {
|
||||
kYUYV(2),
|
||||
kRGB565(3),
|
||||
kBGR(4),
|
||||
kGray(5);
|
||||
kGray(5),
|
||||
kUYVY(6);
|
||||
|
||||
private final int value;
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
// Color convert
|
||||
switch (pixelFormat) {
|
||||
case VideoMode::kRGB565:
|
||||
// If source is YUYV or Gray, need to convert to BGR first
|
||||
// If source is YUYV, UYVY, or Gray, need to convert to BGR first
|
||||
if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
@@ -226,6 +226,14 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
} else {
|
||||
cur = ConvertYUYVToBGR(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);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kGray) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
@@ -237,7 +245,7 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
}
|
||||
return ConvertBGRToRGB565(cur);
|
||||
case VideoMode::kGray:
|
||||
// If source is YUYV or RGB565, need to convert to BGR first
|
||||
// If source is YUYV, UYVY, or RGB565, need to convert to BGR first
|
||||
if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
@@ -246,6 +254,14 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
} else {
|
||||
cur = ConvertYUYVToBGR(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);
|
||||
}
|
||||
} else if (cur->pixelFormat == VideoMode::kRGB565) {
|
||||
// Check to see if BGR version already exists...
|
||||
if (Image* newImage =
|
||||
@@ -260,6 +276,8 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
case VideoMode::kMJPEG:
|
||||
if (cur->pixelFormat == VideoMode::kYUYV) {
|
||||
cur = ConvertYUYVToBGR(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kUYVY) {
|
||||
cur = ConvertUYVYToBGR(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kRGB565) {
|
||||
cur = ConvertRGB565ToBGR(cur);
|
||||
} else if (cur->pixelFormat == VideoMode::kGray) {
|
||||
@@ -271,6 +289,7 @@ Image* Frame::ConvertImpl(Image* image, VideoMode::PixelFormat pixelFormat,
|
||||
}
|
||||
break;
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kUYVY:
|
||||
default:
|
||||
return nullptr; // Unsupported
|
||||
}
|
||||
@@ -351,6 +370,28 @@ Image* Frame::ConvertYUYVToBGR(Image* image) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Image* Frame::ConvertUYVYToBGR(Image* image) {
|
||||
if (!image || image->pixelFormat != VideoMode::kUYVY) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Allocate a BGR image
|
||||
auto newImage =
|
||||
m_impl->source.AllocImage(VideoMode::kBGR, image->width, image->height,
|
||||
image->width * image->height * 3);
|
||||
|
||||
// Convert
|
||||
cv::cvtColor(image->AsMat(), newImage->AsMat(), cv::COLOR_YUV2BGR_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;
|
||||
|
||||
@@ -195,6 +195,7 @@ class Frame {
|
||||
Image* ConvertMJPEGToBGR(Image* image);
|
||||
Image* ConvertMJPEGToGray(Image* image);
|
||||
Image* ConvertYUYVToBGR(Image* image);
|
||||
Image* ConvertUYVYToBGR(Image* image);
|
||||
Image* ConvertBGRToRGB565(Image* image);
|
||||
Image* ConvertRGB565ToBGR(Image* image);
|
||||
Image* ConvertBGRToGray(Image* image);
|
||||
|
||||
@@ -74,6 +74,7 @@ class Image {
|
||||
switch (pixelFormat) {
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kRGB565:
|
||||
case VideoMode::kUYVY:
|
||||
type = CV_8UC2;
|
||||
break;
|
||||
case VideoMode::kBGR:
|
||||
|
||||
@@ -460,6 +460,9 @@ void MjpegServerImpl::ConnThread::SendHTML(wpi::raw_ostream& os,
|
||||
case VideoMode::kGray:
|
||||
os << "gray";
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
os << "UYVY";
|
||||
break;
|
||||
default:
|
||||
os << "unknown";
|
||||
break;
|
||||
@@ -569,6 +572,9 @@ void MjpegServerImpl::ConnThread::SendJSON(wpi::raw_ostream& os,
|
||||
case VideoMode::kGray:
|
||||
os << "gray";
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
os << "UYVY";
|
||||
break;
|
||||
default:
|
||||
os << "unknown";
|
||||
break;
|
||||
@@ -740,8 +746,9 @@ void MjpegServerImpl::ConnThread::SendStream(wpi::raw_socket_ostream& os) {
|
||||
// for adding it if required.
|
||||
addDHT = JpegNeedsDHT(data, &size, &locSOF);
|
||||
break;
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kUYVY:
|
||||
case VideoMode::kRGB565:
|
||||
case VideoMode::kYUYV:
|
||||
default:
|
||||
// Bad frame; sleep for 10 ms so we don't consume all processor time.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
@@ -26,6 +26,7 @@ void RawSourceImpl::PutFrame(const CS_RawFrame& image) {
|
||||
switch (image.pixelFormat) {
|
||||
case VideoMode::kYUYV:
|
||||
case VideoMode::kRGB565:
|
||||
case VideoMode::kUYVY:
|
||||
type = CV_8UC2;
|
||||
break;
|
||||
case VideoMode::kBGR:
|
||||
|
||||
@@ -198,6 +198,8 @@ bool SourceImpl::SetConfigJson(const wpi::json& config, CS_Status* status) {
|
||||
mode.pixelFormat = cs::VideoMode::kBGR;
|
||||
} else if (wpi::equals_lower(str, "gray")) {
|
||||
mode.pixelFormat = cs::VideoMode::kGray;
|
||||
} else if (wpi::equals_lower(str, "uyvy")) {
|
||||
mode.pixelFormat = cs::VideoMode::kUYVY;
|
||||
} else {
|
||||
SWARNING("SetConfigJson: could not understand pixel format value '{}'",
|
||||
str);
|
||||
@@ -360,6 +362,9 @@ wpi::json SourceImpl::GetConfigJsonObject(CS_Status* status) {
|
||||
case VideoMode::kGray:
|
||||
pixelFormat = "gray";
|
||||
break;
|
||||
case VideoMode::kUYVY:
|
||||
pixelFormat = "uyvy";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,8 @@ enum CS_PixelFormat {
|
||||
CS_PIXFMT_YUYV,
|
||||
CS_PIXFMT_RGB565,
|
||||
CS_PIXFMT_BGR,
|
||||
CS_PIXFMT_GRAY
|
||||
CS_PIXFMT_GRAY,
|
||||
CS_PIXFMT_UYVY
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,7 +68,8 @@ struct VideoMode : public CS_VideoMode {
|
||||
kYUYV = CS_PIXFMT_YUYV,
|
||||
kRGB565 = CS_PIXFMT_RGB565,
|
||||
kBGR = CS_PIXFMT_BGR,
|
||||
kGray = CS_PIXFMT_GRAY
|
||||
kGray = CS_PIXFMT_GRAY,
|
||||
kUYVY = CS_PIXFMT_UYVY
|
||||
};
|
||||
VideoMode() {
|
||||
pixelFormat = 0;
|
||||
|
||||
@@ -82,6 +82,8 @@ static VideoMode::PixelFormat ToPixelFormat(__u32 pixelFormat) {
|
||||
return VideoMode::kBGR;
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
return VideoMode::kGray;
|
||||
case V4L2_PIX_FMT_UYVY:
|
||||
return VideoMode::kUYVY;
|
||||
default:
|
||||
return VideoMode::kUnknown;
|
||||
}
|
||||
@@ -100,6 +102,8 @@ static __u32 FromPixelFormat(VideoMode::PixelFormat pixelFormat) {
|
||||
return V4L2_PIX_FMT_BGR24;
|
||||
case VideoMode::kGray:
|
||||
return V4L2_PIX_FMT_GREY;
|
||||
case VideoMode::kUYVY:
|
||||
return V4L2_PIX_FMT_UYVY;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -368,6 +368,12 @@ void UsbCameraImpl::ProcessFrame(IMFSample* videoSample,
|
||||
tmpMat.total() * 2);
|
||||
tmpMat.copyTo(dest->AsMat());
|
||||
break;
|
||||
case cs::VideoMode::PixelFormat::kUYVY:
|
||||
tmpMat = cv::Mat(mode.height, mode.width, CV_8UC2, ptr, pitch);
|
||||
dest = AllocImage(VideoMode::kUYVY, tmpMat.cols, tmpMat.rows,
|
||||
tmpMat.total() * 2);
|
||||
tmpMat.copyTo(dest->AsMat());
|
||||
break;
|
||||
default:
|
||||
doFinalSet = false;
|
||||
break;
|
||||
@@ -472,6 +478,8 @@ static cs::VideoMode::PixelFormat GetFromGUID(const GUID& guid) {
|
||||
return cs::VideoMode::PixelFormat::kMJPEG;
|
||||
} else if (IsEqualGUID(guid, MFVideoFormat_RGB565)) {
|
||||
return cs::VideoMode::PixelFormat::kRGB565;
|
||||
} else if (IsEqualGUID(guid, MFVideoFormat_UYVY)) {
|
||||
return cs::VideoMode::PixelFormat::kUYVY;
|
||||
} else {
|
||||
return cs::VideoMode::PixelFormat::kUnknown;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user