OpenCv: 如何将矢量转换为<Point>垫子 (CV_8U)

OpenCv: How to convert vector<Point> to Mat (CV_8U)

本文关键字:垫子 gt Point CV 8U lt 转换 OpenCv      更新时间:2023-10-16

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

我有一个vector<Point>,它在图像上存储了许多坐标。我想:

  1. 创建类型为 CV_8U 的空白白色垫
  2. 对于坐标向量中的每个点,我想在白色图像上用黑色标记该点,
  3. 打印图像。

下面是遍历向量的函数:

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

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

我错过了什么?指针相关问题?垫子初始化问题?

<--->

第一个答案之后,我发现实际问题是我无法在 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)有关吗?

我希望这会有所帮助,但尚未测试。

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

你可以改为:

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
}

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

在对我的代码进行彻底分析后,我检测到存储在向量中的坐标是相对于一个更大的 Mat,比如 Mat OldImageMat NewImage旨在存储 Mat OldImage 点的子集(NewImage比 OldImage 小得多),但由于没有从一个坐标系到另一个坐标系的坐标转换,我总是写错位置。

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