问题描述:经过语义分割模型输出的分割结果保存在一个cv::Mat变量中,如何快速找到cv::Mat中标签为具体值(例如寻找的标签为13)的坐标,并进行上色呢?
方法1:用for循环对cv::mat 矩阵进行遍历
for (int i = 0; i < imgrow; i++) { //遍历行
for (int j = 0; j < imgcol; j++) { //遍历列
int index_row=i,index_col=j;
int class_Label = mat.at<int>(i, j);
if(class_Label==13)
rgbImage.at<cv::Vec3b>(index_row, index_col) = colors[13];
}
缺点:用for循环的方式遍历整个cv::mat,是一个非常耗时的操作,经过测试,这组代码运行时间需要1s以上。
方法2:使用cv自带的函数去访问cv::mat
cv::Mat mask = (mat == 13);
cv::Mat locations;
cv::findNonZero(mask, locations);
for (int i = 0; i < locations.rows; i++)
{
int x = locations.at<int>(i, 0);
int y = locations.at<int>(i, 1);
rgbImage.at<cv::Vec3b>(y, x) = colors[13];
}
在这个例子中,使用mat == 13
创建一个布尔掩码 mask
,其中值为 true
的元素对应的是像素值为 13 的像素。接着,使用 cv::findNonZero
函数找到掩码中所有非零元素的坐标,并将它们存储在 locations
中。locations 中每一行的前两个元素即为一个值为 13 的像素的 x 和 y 坐标。
经过测试,这种方法运行时间只有1ms左右,运行速度大大提升。