将给定 "type" 文件中的图像加载到 OpenCV Mat 中?
Loading image from file as given "type" into an OpenCV Mat?
我最近开始使用 OpenCV 的 Java 绑定来制作一个快速而肮脏的项目来进行模板匹配。基本上我试图将一组 jpg 图像(保存在 MS Paint 中)读入 Mat
s,然后使用模板匹配从使用 Java.Robot
.
拍摄的屏幕截图中找到它们的位置
进行模板匹配时抛出此错误
OpenCV Error: Assertion failed ((depth == CV_8U || depth == CV_32F)
&& type == _templ.type() && _img.dims() <= 2) in cv::matchTemplate
it looks like the issue is that the two Mat
s I am trying to use do not have the same "type". What I am not sure of is what this refers to. I assume it is the Mat
s CvType
, if I print out the CvType
of the image and template I get a type()
of 4 == CvType.CV_32SC1
对于我的模板,我得到 20 == CvType.CV_32SC3
的 type()
。
但是我感觉这样不对type()
我在比较,我感觉它指的是数据是如何存储在Mat
中的数据类型?但是我没有很好的链接来支持这一点,只是来自许多 SO 搜索的记忆。
这是我将 jpg 图像加载到 Mat
中的代码
Mat pic_ = Imgcodecs.imread("MyPath\image.jpg");
pic_.convertTo(pic_, CvType.CV_32SC1);
此处第二行将我的 type()
从 20 变为 16,但根据我的上一条评论,我认为这不是更改 Mat
以匹配图像的正确方法? ... 因为 convertTo
'ing 这个 Mat
来匹配屏幕截图的类型`(下面)没有修复错误?
这是我创建图像的方式Mat
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenShot = rob.createScreenCapture(screenRect);
Mat screenImage = bufferedImageToMat(screenShot);
所以我先用 Java.Robot.createScreenCapture
截图,然后用
把它转换成 Mat
private Mat bufferedImageToMat(BufferedImage inBuffImg)
{
BufferedImage image = new BufferedImage(inBuffImg.getWidth(), inBuffImg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d= image.createGraphics();
g2d.drawImage(inBuffImg, 0, 0, null);
g2d.dispose();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_32SC1);
int[] data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
mat.put(0, 0, data);
return mat;
}
From what I could tell Robot
创建的 BufferedImage
是 BufferedImage.TYPE_3BYTE_BGR
类型,在尝试获取像素数据时出现错误 "DataBufferInt cannot be cast to DataBufferByte"。因此,根据链接的问题,我将 BufferedImage
重新绘制为类型 BufferedImage.TYPE_INT_RGB
,并将数据提取为 DataBufferInt
。
总而言之, 我应该尝试匹配 Mat.type()
还是我的问题出在其他地方?如果不是在其他地方,我该如何更改 Mat
中的任何一个,以便它们可以正确地与 Imgproc.matchTemplate
一起使用?
我觉得最简单的解决方案是转换从文件加载的图像以匹配屏幕截图Mat
?
编辑: 给出错误的确切代码部分如下
// Mat imageTemplate is a function argument; the loaded jpg image
// Take a picture of the screen
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenShot = rob.createScreenCapture(screenRect);
Mat screenImage = bufferedImageToMat(screenShot);
// Create the result matrix
int result_cols = screenImage.cols() - imageTemplate.cols() + 1;
int result_rows = screenImage.rows() - imageTemplate.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32SC1);
newStatus("ScreenType: " + screenImage.type());
newStatus("TemplaType: " + imageTemplate.type());
// Choose a matching method
int matchMethod = Imgproc.TM_SQDIFF_NORMED;
// Do the Matching and Normalize
Imgproc.matchTemplate(screenImage, imageTemplate, result, matchMethod);
// Error occurs on previous line
正如@Miki 在评论中指出的那样,答案是让频道类型与图像和模板相匹配。我最终更改了 bufferedImageToMat
函数。
private Mat bufferedImageToMat(BufferedImage inBuffImg)
{
BufferedImage image = new BufferedImage(inBuffImg.getWidth(), inBuffImg.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d= image.createGraphics();
g2d.drawImage(inBuffImg, 0, 0, null);
g2d.dispose();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
mat.put(0, 0, data);
return mat;
}
我的模板被读取为 CvType.CV_8UC3
,因此只需使用此类型从屏幕图像创建 Mat
!
我最近开始使用 OpenCV 的 Java 绑定来制作一个快速而肮脏的项目来进行模板匹配。基本上我试图将一组 jpg 图像(保存在 MS Paint 中)读入 Mat
s,然后使用模板匹配从使用 Java.Robot
.
进行模板匹配时抛出此错误
OpenCV Error: Assertion failed ((depth == CV_8U || depth == CV_32F)
&& type == _templ.type() && _img.dims() <= 2) in cv::matchTemplate
Mat
s I am trying to use do not have the same "type". What I am not sure of is what this refers to. I assume it is the Mat
s CvType
, if I print out the CvType
of the image and template I get a type()
of 4 == CvType.CV_32SC1
对于我的模板,我得到 20 == CvType.CV_32SC3
的 type()
。
但是我感觉这样不对type()
我在比较,我感觉它指的是数据是如何存储在Mat
中的数据类型?但是我没有很好的链接来支持这一点,只是来自许多 SO 搜索的记忆。
这是我将 jpg 图像加载到 Mat
Mat pic_ = Imgcodecs.imread("MyPath\image.jpg");
pic_.convertTo(pic_, CvType.CV_32SC1);
此处第二行将我的 type()
从 20 变为 16,但根据我的上一条评论,我认为这不是更改 Mat
以匹配图像的正确方法? ... 因为 convertTo
'ing 这个 Mat
来匹配屏幕截图的类型`(下面)没有修复错误?
这是我创建图像的方式Mat
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenShot = rob.createScreenCapture(screenRect);
Mat screenImage = bufferedImageToMat(screenShot);
所以我先用 Java.Robot.createScreenCapture
截图,然后用
Mat
private Mat bufferedImageToMat(BufferedImage inBuffImg)
{
BufferedImage image = new BufferedImage(inBuffImg.getWidth(), inBuffImg.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d= image.createGraphics();
g2d.drawImage(inBuffImg, 0, 0, null);
g2d.dispose();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_32SC1);
int[] data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
mat.put(0, 0, data);
return mat;
}
From what I could tell Robot
创建的 BufferedImage
是 BufferedImage.TYPE_3BYTE_BGR
类型,在尝试获取像素数据时出现错误 "DataBufferInt cannot be cast to DataBufferByte"。因此,根据链接的问题,我将 BufferedImage
重新绘制为类型 BufferedImage.TYPE_INT_RGB
,并将数据提取为 DataBufferInt
。
总而言之, 我应该尝试匹配 Mat.type()
还是我的问题出在其他地方?如果不是在其他地方,我该如何更改 Mat
中的任何一个,以便它们可以正确地与 Imgproc.matchTemplate
一起使用?
我觉得最简单的解决方案是转换从文件加载的图像以匹配屏幕截图Mat
?
编辑: 给出错误的确切代码部分如下
// Mat imageTemplate is a function argument; the loaded jpg image
// Take a picture of the screen
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage screenShot = rob.createScreenCapture(screenRect);
Mat screenImage = bufferedImageToMat(screenShot);
// Create the result matrix
int result_cols = screenImage.cols() - imageTemplate.cols() + 1;
int result_rows = screenImage.rows() - imageTemplate.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32SC1);
newStatus("ScreenType: " + screenImage.type());
newStatus("TemplaType: " + imageTemplate.type());
// Choose a matching method
int matchMethod = Imgproc.TM_SQDIFF_NORMED;
// Do the Matching and Normalize
Imgproc.matchTemplate(screenImage, imageTemplate, result, matchMethod);
// Error occurs on previous line
正如@Miki 在评论中指出的那样,答案是让频道类型与图像和模板相匹配。我最终更改了 bufferedImageToMat
函数。
private Mat bufferedImageToMat(BufferedImage inBuffImg)
{
BufferedImage image = new BufferedImage(inBuffImg.getWidth(), inBuffImg.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d= image.createGraphics();
g2d.drawImage(inBuffImg, 0, 0, null);
g2d.dispose();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
mat.put(0, 0, data);
return mat;
}
我的模板被读取为 CvType.CV_8UC3
,因此只需使用此类型从屏幕图像创建 Mat
!