从IplImage到Mat的转换,缺少cvarrToMat /跳过图像数据字节

时间:2019-03-11 12:14:32

标签: c++ opencv

我正在尝试将图像从容器IplImage转换为Mat对象,而不是使用cvarrToMat

我意识到转换后的Mat图像将在末尾显示许多随机数据字节(也就是内存中一些未初始化的字节),但是我不明白为什么会这样和/或如何解决?请参见下面的代码和结果。

我正在使用opencv 2.4.13.7并在Visual Studio 2017(Visual C ++ 2017)中工作

我制作了一个像素可识别数据的数据数组,其中包含深度为8位和3个彩色通道的3 * 4分辨率图像的数据。打印转换后的图像中的数据时,表明它在数据的每一行末尾都跳过了一个像素(3个字节)。

#include "pch.h"
#include <iostream>
#include "cv.hpp"
#include "highgui.hpp"

using namespace std;
using namespace cv;

int main()
{
IplImage* ipl = NULL;
const char* windowName = "Mat image";
int i = 0;

ipl = cvCreateImage(cvSize(3, 4), IPL_DEPTH_8U, 3);
char array[3* 4 * 3] = { 11,12,13, 21,22,23, 31,32,33, 41,42,43, 51, 52, 53, 61, 62, 63, 71, 72, 73, 81, 82, 83, 91, 92, 93, 101, 102, 103, 111, 112, 113, 121, 122, 123 };

ipl->imageData = array;

printf("ipl->imageData = [ ");
for (i = 0; i < (ipl->width*ipl->height*ipl->nChannels); i++) {
    printf("%u, ", ipl->imageData[i]);
}
printf("]\n\n");


Mat ipl2 = cvarrToMat(ipl);
cout << "ipl2 = " << endl << " " << ipl2 << endl << endl;

//display dummy image in window to use waitKey function
Mat M(3, 3, CV_8UC3, Scalar(0, 0, 255));
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
imshow(windowName, M);

waitKey(0);

cvReleaseImage(&ipl);
}

结果: Console window output for 3*4 resolution image

如果仅对2 * 2像素分辨率的图像执行相同操作,则在行尾仅跳过两个字节。.我也无法解释这一点。

Console window output for same code only with 2*2 resolution image

我要进行此转换的原因是因为我在C中有一个工作例程,可以将图像数据从文件(关于带有原始图像数据的旧图像文件格式的长篇故事)导入IplImage进行进一步处理,我想保留一下-但我想开始以Mat格式处理图像,因为它似乎得到了更广泛的支持,并且通常更易于使用,至少直到我看到为止。

1 个答案:

答案 0 :(得分:0)

免责声明:这不是对问题本身的答案,但应有助于作者进一步调查他的问题。另外,请参阅问题下方的评论。

作为一个小测试,我使用此3x3图像(您几乎看不到-看看我对链接的问题的“原始”输入):

Small 3x3 image

图像监视(Visual Studio扩展)中,它看起来像这样:

Visualisation

让我们尝试以下代码:

    // Read input image.
    cv::Mat img = cv::imread("test.png", cv::IMREAD_COLOR);

    // Output pixel values.
    for (int x = 0; x < img.cols; x++)
    {
        for (int y = 0; y < img.rows; y++)
        {
            printf("%d ", img.at<cv::Vec3b>(y, x)[0]);
            printf("%d ", img.at<cv::Vec3b>(y, x)[1]);
            printf("%d \n", img.at<cv::Vec3b>(y, x)[2]);
        }
    }

我们将获得以下输出:

0 255 255
0 255 255
255 255 255
255 0 255
255 255 255
255 0 255
0 0 255
0 255 255
255 0 255

现在,您可以使用嵌套循环来检查IplImage iplMat ipl2中的图像数据(或更佳:像素值)是否相同。