OpenCv:如何将vector <point>转换为Mat(CV_8U)</point>

时间:2013-01-30 21:48:31

标签: c++ opencv vector matrix

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

我有vector<Point>在图片上存储多个坐标。 我想:

  1. 创建CV_8U
  2. 类型的空白白色垫子
  3. 对于坐标向量中的每个点,我想在白色图像上将该点标记为黑色,
  4. 打印图像。
  5. 这是迭代向量的函数:

    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);
    
        }
    
        ...
    
     }
    

    这是我的打印功能

    void Utility::DisplayImage(Mat& tgtImage) {
    
        namedWindow("Draw Image", (CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO));
        imshow("Draw Image", tgtImage);
        waitKey(0);
    
    }
    

    我的问题如下:看起来这些值存储在Matrix中(我尝试打印它们),但DisplayImage函数(在所有其他情况下都能正常工作)一直向我显示空白图像。

    我缺少什么?与指针有关的问题? Mat初始化问题?

    &lt; --- --- --- UPDATE --- --- ---&gt;

    在第一个答案之后,我发现实际问题是我无法在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;
    }
    

    结果总是如此:

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

    所以价值没有设定,任何想法?

    可能是与图像类型相关的东西(CV_8U)??

3 个答案:

答案 0 :(得分:1)

我希望这会有所帮助,而不是测试。

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);

答案 1 :(得分:1)

你可以这样做:

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
}

这省去了直接数据访问和指针操作,并且更具可读性。

答案 2 :(得分:1)

在对我的代码进行彻底分析后,我发现存储在向量中的坐标相对于较大的Mat,比如Mat OldImage Mat NewImage旨在存储Matle点OldImage的一个子集(NewImage远小于OldImage),但是没有从一个坐标系到另一个坐标系的坐标转换,总是写错了。

我通过使用简单的减法将点转换为正确的坐标系来解决问题。