OpenCV-2.4.8.2:imshow 与 imwrite 不同
Posted
技术标签:
【中文标题】OpenCV-2.4.8.2:imshow 与 imwrite 不同【英文标题】:OpenCV-2.4.8.2: imshow differs from imwrite 【发布时间】:2015-04-23 06:22:30 【问题描述】:我在 Mac OS 10.9.5 上使用 OpenCV2.4.8.2。 我有以下 sn-p 代码:
static void compute_weights(const vector<Mat>& images, vector<Mat>& weights)
weights.clear();
for (int i = 0; i < images.size(); i++)
Mat image = images[i];
Mat mask = Mat::zeros(image.size(), CV_32F);
int x_start = (i == 0) ? 0 : image.cols/2;
int y_start = 0;
int width = image.cols/2;
int height = image.rows;
Mat roi = mask(Rect(x_start,y_start,width,height)); // Set Roi
roi.setTo(1);
weights.push_back(mask);
static void blend(const vector<Mat>& inputImages, Mat& outputImage)
int maxPyrIndex = 6;
vector<Mat> weights;
compute_weights(inputImages, weights);
// Find the fused pyramid:
vector<Mat> fused_pyramid;
for (int i = 0; i < inputImages.size(); i++)
Mat image = inputImages[i];
// Build Gaussian Pyramid for Weights
vector<Mat> weight_gaussian_pyramid;
buildPyramid(weights[i], weight_gaussian_pyramid, maxPyrIndex);
// Build Laplacian Pyramid for original image
Mat float_image;
inputImages[i].convertTo(float_image, CV_32FC3, 1.0/255.0);
vector<Mat> orig_guassian_pyramid;
vector<Mat> orig_laplacian_pyramid;
buildPyramid(float_image, orig_guassian_pyramid, maxPyrIndex);
for (int j = 0; j < orig_guassian_pyramid.size() - 1; j++)
Mat sized_up;
pyrUp(orig_guassian_pyramid[j+1], sized_up, Size(orig_guassian_pyramid[j].cols, orig_guassian_pyramid[j].rows));
orig_laplacian_pyramid.push_back(orig_guassian_pyramid[j] - sized_up);
// Last Lapalcian layer is the same as the Gaussian layer
orig_laplacian_pyramid.push_back(orig_guassian_pyramid[orig_guassian_pyramid.size()-1]);
// Convolve laplacian original with guassian weights
vector<Mat> convolved;
for (int j = 0; j < maxPyrIndex + 1; j++)
// Create 3 channels for weight gaussian pyramid as well
vector<Mat> gaussian_3d_vec;
for (int k = 0; k < 3; k++)
gaussian_3d_vec.push_back(weight_gaussian_pyramid[j]);
Mat gaussian_3d;
merge(gaussian_3d_vec, gaussian_3d);
//Mat convolved_result = weight_gaussian_pyramid[j].clone();
Mat convolved_result = gaussian_3d.clone();
multiply(gaussian_3d, orig_laplacian_pyramid[j], convolved_result);
convolved.push_back(convolved_result);
if (i == 0)
fused_pyramid = convolved;
else
for (int j = 0; j < maxPyrIndex + 1; j++)
fused_pyramid[j] += convolved[j];
// Blending
for (int i = (int)fused_pyramid.size()-1; i > 0; i--)
Mat sized_up;
pyrUp(fused_pyramid[i], sized_up, Size(fused_pyramid[i-1].cols, fused_pyramid[i-1].rows));
fused_pyramid[i-1] += sized_up;
Mat final_color_bgr;
fused_pyramid[0].convertTo(final_color_bgr, CV_32F, 255);
final_color_bgr.copyTo(outputImage);
imshow("final", outputImage);
waitKey(0);
imwrite(outputImagePath, outputImage);
此代码正在对 2 张图像进行一些基本的金字塔混合。关键问题与最后一行中的 imshow 和 imwrite 有关。他们给了我截然不同的结果。对于显示如此长/混乱的代码,我深表歉意,但我担心这种差异来自代码的其他部分,这些部分随后会影响 imshow 和 imwrite。
根据给定的代码,第一张图片显示了 imwrite 的结果,第二张图片显示了 imshow 的结果。我很困惑为什么会这样。
我还注意到,当我这样做时:
Mat float_image;
inputImages[i].convertTo(float_image, CV_32FC3, 1.0/255.0);
imshow("float image", float_image);
imshow("orig image", image);
它们显示的内容完全相同,即它们都在原始 rgb 图像(图像中)中显示相同的图片。
【问题讨论】:
浮点值的 imshow 表示 0 = 黑色和 1 = 白色,因此全白图像可能具有错误比例的强度值。 嗨米卡,感谢您的回复。但是为什么imwrite是好的?你对比例是正确的。如果我在接近尾声时将其缩放 1,则 imshow 是可以的,但 imwrite 是全黑的...... 可能,imwrite 和 imshow 对值范围使用不同的假设;)您写入的文件扩展名是什么?也许该文件扩展名甚至可以直接处理浮点数,或者只执行类型转换而不缩放值(而 imshow 将浮点值乘以 255!)。 OpenCV 文档对 imwrite 说:Only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function. If the format, depth or channel order is different, use Mat::convertTo() , and cvtColor() to convert it before saving
因此,如果您的值在 0 和 1 之间缩放,您的 imwrite 会将值转换为 8 位通道值中的 0 或 1,这是非常黑色的。见文档:docs.opencv.org/modules/highgui/doc/…
谢谢 Micka 和下面的帖子。它解决了这个问题。 :)
【参考方案1】:
IMWRITE 功能
默认情况下,imwrite 将输入图像转换为 仅 8 位(或在 PNG、JPEG 2000 和 TIFF 的情况下为 16 位无符号 (CV_16U))单通道或 3 通道(具有“BGR”通道顺序)图像可以使用此功能保存。 因此,无论您为 imwrite 输入什么格式,它都会盲目地转换为 CV_8U,范围为 0(黑色)- 255(白色),采用 BGR 格式。
IMSHOW - 问题
所以当注意到你的函数时,fused_pyramid[0].convertTo(final_color_bgr, CV_32F, 255);
fused_pyramid 已经在垫类型 21(浮点 CV_32F)下。您尝试使用比例因子 255 转换为浮点数。这个比例因子 255 导致了@imshow 的问题。代替可视化,您可以直接输入 fused_pyramid 而无需转换,因为它已经缩放到 0.0(black) - 1.0(white) 之间的浮点数。
希望对您有所帮助。
【讨论】:
谢谢斯里拉姆。你的解释很有见地。我再也不会犯这个错误了。以上是关于OpenCV-2.4.8.2:imshow 与 imwrite 不同的主要内容,如果未能解决你的问题,请参考以下文章