OpenCV:断言失败“dst.data == widget->original_image->data.ptr 函数 'cvImageWidgetSetImage'”
OpenCV: Assertion failed " dst.data == widget->original_image->data.ptr in function 'cvImageWidgetSetImage' "
重要提示: 我解决了这个问题。 解决在最后。
我要达到什么目的?
使用 OpenCV cv::imshow 方法显示图像。 (imshow Documentation)
3x3 矩阵的图像是这样创建的:
Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, -4, 1, 0, 1, 0});
显示图片我调用imshow("mask", mask);
我的问题是什么?
就像我在标题中提到的那样,在尝试显示图像时抛出了异常。完整的错误消息:
terminate called after throwing an instance of 'cv::Exception' what():
OpenCV(4.0.0-pre) /home/mrlab/Libraries/opencv_source/modules/highgui
/src/window_gtk.cpp:146: error: (-215:Assertion failed)
dst.data == widget->original_image->data.ptr in function 'cvImageWidgetSetImage'
Link 到 window_gtk.cpp
我已经尝试了什么?
- 正在网上查找错误。也许其他人已经遇到了同样的问题。 不。什么都没有
- 将矩阵更改为仅包含正浮点值(0 到 1),以防出现负输入问题。初始化:
Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, 0, 1, 0, 1, 0});
同样错误
- 在不同的位置调用这两种方法,以防在我的其他代码中发生更改。 同样的错误
- 编写小型 OpenCV 程序只需 运行 这两行。 同样的错误
- 上述想法的各种组合。 同样的错误
- 显示我从记忆中读取的其他图像,而不是自己创建它们。 工作得很好
- 通过
imwrite("mask.png", mask)
保存图像看起来像
this。我知道的很小。我将值缩放到 0 到 255 的范围内,因为这是 png 需要的。 工作得很好
围绕我损坏的行完成代码:
void high_pass(){
Mat src_f;
// Fourier transform src_bw
src_f = fourier(src_bw);
// Create Laplace High Pass Kernel
Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, -4, 1, 0, 1, 0});
// In case of using fp values (0 to 1) initialize like this:
// Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, 0, 1, 0, 1, 0});
imshow("mask", mask);
// Fourier transform kernel
Mat mask_f = fourier_kernel(mask, src_f.size());
Mat hp_filtered;
// Apply filter
mulSpectrums(src_f, mask_f, hp_filtered, DFT_ROWS);
// Transform it back
dst = fourier_inv(hp_filtered);
// Swap quadrants after applying filter
dst = swap_quadrants(dst);
// Show result
//imshow(WINDOW_NAME + "high pass", dst);
}
仅供参考: 最后一行引发了相同的异常,这就是它被注释掉的原因。我用 "mask" 问问题,因为它更容易。
写完这个问题我又有了新的想法。
解决方案: 我将 CV_32F
类型矩阵转换为 CV_8U
矩阵并将所有值缩放到 0 到 255 范围内。这解决了问题。
这是我应该首先想到的。出于某种原因,我花了一个小时才意识到。以防万一其他人遇到同样的错误或精神障碍我仍然post这里。
解决方案: 我将 CV_32F 类型矩阵转换为 CV_8U 矩阵并将所有值缩放到 0 到 255 的范围内。这解决了问题。
编辑: 如 Nikolaj Fogh 所述,也可以恢复到 OpenCV 版本 3.4.3。我没有亲自测试。
为了完整起见,这是实现 Philipp 解决方案的方法(使用他的程序的变量):
cv::Mat dist_8U; // to store the scaled image with appropriate type
double Min,Max;
cv::minMaxLoc(rgb,&Min,&Max);
dist -= Min;
dist.convertTo(dist_8U,CV_8U,255.0/(Max-Min));
那么dist_8U
在opencv 4.0.0中可以用imshow
显示。
在 raspberry pi.
上测试
重要提示: 我解决了这个问题。 解决在最后。
我要达到什么目的? 使用 OpenCV cv::imshow 方法显示图像。 (imshow Documentation)
3x3 矩阵的图像是这样创建的:
Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, -4, 1, 0, 1, 0});
显示图片我调用imshow("mask", mask);
我的问题是什么? 就像我在标题中提到的那样,在尝试显示图像时抛出了异常。完整的错误消息:
terminate called after throwing an instance of 'cv::Exception' what():
OpenCV(4.0.0-pre) /home/mrlab/Libraries/opencv_source/modules/highgui
/src/window_gtk.cpp:146: error: (-215:Assertion failed)
dst.data == widget->original_image->data.ptr in function 'cvImageWidgetSetImage'
Link 到 window_gtk.cpp
我已经尝试了什么?
- 正在网上查找错误。也许其他人已经遇到了同样的问题。 不。什么都没有
- 将矩阵更改为仅包含正浮点值(0 到 1),以防出现负输入问题。初始化:
Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, 0, 1, 0, 1, 0});
同样错误 - 在不同的位置调用这两种方法,以防在我的其他代码中发生更改。 同样的错误
- 编写小型 OpenCV 程序只需 运行 这两行。 同样的错误
- 上述想法的各种组合。 同样的错误
- 显示我从记忆中读取的其他图像,而不是自己创建它们。 工作得很好
- 通过
imwrite("mask.png", mask)
保存图像看起来像 this。我知道的很小。我将值缩放到 0 到 255 的范围内,因为这是 png 需要的。 工作得很好
围绕我损坏的行完成代码:
void high_pass(){
Mat src_f;
// Fourier transform src_bw
src_f = fourier(src_bw);
// Create Laplace High Pass Kernel
Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, -4, 1, 0, 1, 0});
// In case of using fp values (0 to 1) initialize like this:
// Mat mask(3, 3, CV_32F, new float[9]{0, 1, 0, 1, 0, 1, 0, 1, 0});
imshow("mask", mask);
// Fourier transform kernel
Mat mask_f = fourier_kernel(mask, src_f.size());
Mat hp_filtered;
// Apply filter
mulSpectrums(src_f, mask_f, hp_filtered, DFT_ROWS);
// Transform it back
dst = fourier_inv(hp_filtered);
// Swap quadrants after applying filter
dst = swap_quadrants(dst);
// Show result
//imshow(WINDOW_NAME + "high pass", dst);
}
仅供参考: 最后一行引发了相同的异常,这就是它被注释掉的原因。我用 "mask" 问问题,因为它更容易。
写完这个问题我又有了新的想法。
解决方案: 我将 CV_32F
类型矩阵转换为 CV_8U
矩阵并将所有值缩放到 0 到 255 范围内。这解决了问题。
这是我应该首先想到的。出于某种原因,我花了一个小时才意识到。以防万一其他人遇到同样的错误或精神障碍我仍然post这里。
解决方案: 我将 CV_32F 类型矩阵转换为 CV_8U 矩阵并将所有值缩放到 0 到 255 的范围内。这解决了问题。
编辑: 如 Nikolaj Fogh 所述,也可以恢复到 OpenCV 版本 3.4.3。我没有亲自测试。
为了完整起见,这是实现 Philipp 解决方案的方法(使用他的程序的变量):
cv::Mat dist_8U; // to store the scaled image with appropriate type
double Min,Max;
cv::minMaxLoc(rgb,&Min,&Max);
dist -= Min;
dist.convertTo(dist_8U,CV_8U,255.0/(Max-Min));
那么dist_8U
在opencv 4.0.0中可以用imshow
显示。
在 raspberry pi.