OpenCv:如何将vector转换为Mat (CV_8U)

时间:2023-01-31 04:22:42

Hi everybody and thanks for your attention, I have the following problem:

大家好,感谢大家的关注,我有以下问题:

I have a vector<Point> which stores a number of coordinates on an image. I want to:

我有一个向量 ,它在图像上存储一些坐标。我想:

  1. Create a blank white Mat of type CV_8U
  2. 创建一个空白白色的类型CV_8U。
  3. For each Point in the vector of coordinates, I want to mark that Point in black over the white image,
  4. 对于坐标向量中的每一点,我想要用黑色来标记这一点,
  5. Print the image.
  6. 打印图像。

Here is the function iterating over the vector:

这里是迭代矢量的函数:

void Frag::updateImage(vector<Point> points){

    ...

    if(NewHeight > 0 && NewWidth > 0){

        cv::Mat NewImage = cv::Mat(NewHeight, NewWidth, CV_8U, Scalar(255));
        // Is this the correct way to initialize a blank Mat of type CV_8U???

        for (unsigned int i = 0; i < points.size(); i++) {

            uchar* PointPtr = NewImage.ptr<uchar> (points[i].x, points[i].y);
            *PointPtr = 0;
        }

        Utility::DisplayImage(NewImage);

    }

    ...

 }

And here is my print function:

这是我的打印函数:

void Utility::DisplayImage(Mat& tgtImage) {

    namedWindow("Draw Image", (CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO));
    imshow("Draw Image", tgtImage);
    waitKey(0);

}

My problem is the following: it looks like the values are stored into the Matrix (I tried printing them), but the DisplayImage function (which works fine in all the other cases) keeps showing me just blank white images.

我的问题是:看起来这些值存储在矩阵中(我尝试打印它们),但是DisplayImage函数(在所有其他情况下都适用)一直显示我只是空白的白色图像。

What am i missing? Pointer-related issues? Mat initialization issues?

我缺少什么?指示器相关问题?垫的初始化问题?

<--- --- --- UPDATE --- --- --->

<--- --- --- --- --- --- -->。

After the first answers, I found out that the actual issue is that I am not able to set the values in the Mat. I found that because i added a simple loop to print all the values in the Mat (since my Mats are often very small). The loop is the following ( i put it right after the iteration over the vector of Coordinates:

在第一个答案之后,我发现实际的问题是我无法在Mat中设置值。我发现,因为我添加了一个简单的循环来打印Mat中的所有值(因为我的垫子通常很小)。这个循环是下面的(我把它放在坐标矢量的迭代之后:

for(int j = 0; j< NewHeight; j++){
    for(int i = 0; i< NewWidth; i++){
        Logger << (int)NewImage.at<uchar> (i, j) << " ";
    }
    Logger << endl;
}

And its result is always this:

其结果总是这样的:

Creating image with W=2, H=7.
255 255 
255 255 
255 255 
255 255 
255 255 
255 255 
255 255 

So the value are just not set, any idea?

所以这个值是不确定的?

Could it be something related to the image type (CV_8U)??

它是否与图像类型有关(CV_8U)??

3 个解决方案

#1


1  

i hope this will help, not tested yet.

我希望这能对你有所帮助,而不是测试。

Mat NewImage = Mat(NewHeight, NewWidth, CV_8U, Scalar(255));

for(int j = 0; j< NewHeight; j++){
for(int i = 0; i< NewWidth; i++){

for (int k = 0; k < points.size(); k++) {

            if(i==points[k].x && j ==points[k].y)
               NewImage.at<uchar>(j,i) = 0;
        }

}        
}
imshow(NewImage);

#2


1  

You could instead do:

你可以做的:

for (int i =0; i < points.size(); i++)
{
    cv::circle(NewImage, points.at(i), 0, cv::Scalar(0));    //The radius of 0 indicates a single pixel
}

This dispenses with the direct data access and pointer manipulation, and is much more readable.

这就省去了直接的数据访问和指针操作,而且可读性更强。

#3


1  

After a thorough analysis of my code, I detected that the coordinates stored in the vector were relative to a bigger Mat, say Mat OldImage. The Mat NewImage was meant to store a subset of the Points of Mat OldImage (NewImage is much smaller than OldImage), but with no coordinate conversion from one coordinate system to the other, I was always writing in the wrong position.

在对我的代码进行了彻底的分析之后,我发现存储在vector中的坐标相对于一个更大的垫子,比如Mat OldImage。Mat NewImage是用来存储Mat OldImage点的子集(NewImage比OldImage小得多),但是由于没有从一个坐标系到另一个坐标系的坐标转换,所以我总是在错误的位置上写字。

I solved the problem by converting the Points to the correct coordinate system using a simple subtraction.

我用一个简单的减法将这些点转换为正确的坐标系,从而解决了这个问题。

#1


1  

i hope this will help, not tested yet.

我希望这能对你有所帮助,而不是测试。

Mat NewImage = Mat(NewHeight, NewWidth, CV_8U, Scalar(255));

for(int j = 0; j< NewHeight; j++){
for(int i = 0; i< NewWidth; i++){

for (int k = 0; k < points.size(); k++) {

            if(i==points[k].x && j ==points[k].y)
               NewImage.at<uchar>(j,i) = 0;
        }

}        
}
imshow(NewImage);

#2


1  

You could instead do:

你可以做的:

for (int i =0; i < points.size(); i++)
{
    cv::circle(NewImage, points.at(i), 0, cv::Scalar(0));    //The radius of 0 indicates a single pixel
}

This dispenses with the direct data access and pointer manipulation, and is much more readable.

这就省去了直接的数据访问和指针操作,而且可读性更强。

#3


1  

After a thorough analysis of my code, I detected that the coordinates stored in the vector were relative to a bigger Mat, say Mat OldImage. The Mat NewImage was meant to store a subset of the Points of Mat OldImage (NewImage is much smaller than OldImage), but with no coordinate conversion from one coordinate system to the other, I was always writing in the wrong position.

在对我的代码进行了彻底的分析之后,我发现存储在vector中的坐标相对于一个更大的垫子,比如Mat OldImage。Mat NewImage是用来存储Mat OldImage点的子集(NewImage比OldImage小得多),但是由于没有从一个坐标系到另一个坐标系的坐标转换,所以我总是在错误的位置上写字。

I solved the problem by converting the Points to the correct coordinate system using a simple subtraction.

我用一个简单的减法将这些点转换为正确的坐标系,从而解决了这个问题。