大家。我正在尝试使用java和opencv将“.png”图像放在视频捕获上。
我从官方opencv java网站http://opencv-java-tutorials.readthedocs.io/en/latest/04-opencv-basics.html
执行了教程在本教程中,一切都与本教程中的png图像一致。但是当我尝试使用alpha通道加载我自己的png图像时,我得到了错误的结果。 Png图像显示带有空格。
以下是两张图片的视频拍摄打印屏幕:
以下是加载图片的代码:
@FXML
protected void loadLogo() {
if(logoCheckBox.isSelected()) {
this.logo = Imgcodecs.imread("resources/Poli.png", Imgcodecs.IMREAD_COLOR);
}
}
以下是视频捕获代码并在其上放置png图像:
Mat frame = new Mat();
// read the current frame
this.capture.read(frame);
Rect roi = new Rect(frame.cols() - logo.cols(), frame.rows() - logo.rows(), logo.cols(), logo.rows());
Mat imageROI = frame.submat(roi);
Core.addWeighted(imageROI, 1.0, logo, 1.0f, 0.0, imageROI);
以下是输出图像在ImageView中的位置:
MatOfByte buffer = new MatOfByte();
Imgcodecs.imencode(".png", frame, buffer);
Image imageToShow = new Image(new ByteArrayInputStream(buffer.toArray()));
Image imageToShow = Utils.mat2Image(frame);
currentFrame.setImage(imageToShow);
我知道参数Imgcodecs.IMREAD_COLOR加载带有3个通道的图像,没有alpha,但是当我将此参数更改为IMREAD_UNCHANGED时出现此错误:
OpenCV错误:输入参数的大小不匹配(该操作既不是'数组操作数组'(其中数组具有相同的大小和相同的通道数)
这是因为视频捕获的输入Mat只包含3个通道。
我的问题是:如何正确加载png图像并将其放置在视频捕捉上?
P.S当我用黑色填充png图像的背景时,它显示正确,但图像仍保持透明。
答案 0 :(得分:0)
答案,RGBA图像无法放置在RGB视频捕捉上。仅放置png图像的RBG组件会产生错误的结果"。
目前,我找到的最佳解决方案是在4个通道的RBGA模式COLOR_UNCHANCHED中加载png图像,采用第4个alpha通道并将其用作显示图像功能的掩码" copyTo"而不是" addWeighted"。
但是这种方法不适用于PNG图像的半透明部分,如阴影和不透明度低的物体。
以下是使用单独的RGB和Alpha通道加载图像的代码:
Mat logo = new Mat();
Mat logo_alpha = new Mat();
Mat logo_with_alpha = Imgcodecs.imread("resources/TREE_1.png", Imgcodecs.IMREAD_UNCHANGED);
Vector<Mat> rgba = new Vector<Mat>();
// split RBGA image for separate channels
Core.split(logo_with_alpha, rgba);
// get alpha channel
logo_alpha = rgba.get(3);
// remove alpha channel to get RGB image
rgba.remove(rgba.size()-1);
// get image with only RGB components
Core.merge(rgba, this.logo);
以下是视频捕捉和放置png图像的代码:
Mat frame = new Mat();
// read the current frame
this.capture.read(frame);
Rect roi = new Rect(frame.cols() - logo.cols(), frame.rows() - logo.rows(), logo.cols(), logo.rows());
Mat imageROI = frame.submat(roi);
// place logo with alpha on the frame
logo.copyTo(imageROI, logo_alpha);