大家好,感谢您的关注,我有以下问题:
我有一个vector<Point>
,它在图像上存储了许多坐标。我想:
- 创建类型为 CV_8U 的空白白色垫 子
- 对于坐标向量中的每个点,我想在白色图像上用黑色标记该点,
- 打印图像。
下面是遍历向量的函数:
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 OldImage
。Mat NewImage
旨在存储 Mat OldImage
点的子集(NewImage
比 OldImage 小得多),但由于没有从一个坐标系到另一个坐标系的坐标转换,我总是写错位置。
我通过使用简单的减法将点转换为正确的坐标系来解决问题。