C++ 如何使用OpenCV高效地在面具中获得这些独特的标签

C++ 如何使用OpenCV高效地在面具中获得这些独特的标签,c++,opencv,image-processing,C++,Opencv,Image Processing,如果我有这样的标签图像 那么我有这样一个面具 我想在给定的掩码中获得那些唯一的整数标签(与标签图像大小相同)。在本例中,结果是{0,1,2,3,6}。这是我当前的方法 #include<opencv.hpp> #include<string> using namespace std; using namespace cv; int main() { uchar a[6][7] = { { 0,0,0,0,0,0,0 },{ 0,1,2,2,3,3,0 },{

如果我有这样的标签图像

那么我有这样一个面具

我想在给定的掩码中获得那些唯一的整数标签(与标签图像大小相同)。在本例中,结果是
{0,1,2,3,6}
。这是我当前的方法

#include<opencv.hpp>
#include<string>
using namespace std;
using namespace cv;

int main() {
    uchar a[6][7] = { { 0,0,0,0,0,0,0 },{ 0,1,2,2,3,3,0 },{ 0,0,0,0,0,0,0 },{ 0,5,5,6,6,0,0 },{ 0,5,5,6,6,0,0 },{ 0,0,0,0,0,0,0 } };
    Mat label = Mat(6, 7, CV_8UC1, a);
    uchar b[6][7]= { { 0,0,0,0,0,0,0 },{ 0,255,255,255,255,0,0 },{ 255,255,255,0,0,0,0 },{ 0,0,0,255,255,0,0 },{ 0,0,0,255,255,0,0 },{ 0,0,0,0,0,0,0 } };
    Mat mask = Mat(6, 7, CV_8UC1, b);
    vector<int> list;
    for (int i = 0; i < mask.rows; i++) {
        uchar* mask_p = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if (mask_p[j] == 255)
                list.push_back(int(label.at<uchar>(i,j)));
    }
    sort(list.begin(), list.end());
    list.erase(unique(list.begin(), list.end()), list.end());

    return 0;
}
#包括
#包括
使用名称空间std;
使用名称空间cv;
int main(){
uchar a[6][7]={0,0,0,0,0,0},{0,1,2,2,3,3,0},{0,0,0,0,0,0,0},{0,5,5,6,6,0,0},{0,5,5,6,0,0},{0,0,0,0,0};
垫标签=垫(6,7,CV_8UC1,a);
uchar b[6][7]={0,0,0,0,0,0},{0255255,0,0},{255255,0,0,0,0,0},{0,0,0255255,0,0,0,0,0},{0,0,02555,0,0,0},{0,0,0,0,0};
Mat掩模=Mat(6,7,CV_8UC1,b);
向量表;
对于(int i=0;i

但在我的真实案例中,我在一张巨大的蒙版图像中只有一个小的ROI。我认为目前的方法是迭代遮罩中的每个像素,在我的例子中浪费了我太多的时间。有人能给我一些建议吗?

这种新方法可以避免迭代每个像素,这在巨大的
遮罩中更快

#include<string>
#include<opencv.hpp>
using namespace std;
using namespace cv;

int main() {
    uchar a[6][7] = { { 0,0,0,0,0,0,0 },{ 0,1,2,2,3,3,0 },{ 0,0,0,0,0,0,0 },{ 0,5,5,6,6,0,0 },{ 0,5,5,6,6,0,0 },{ 0,0,0,0,0,0,0 } };
    Mat label = Mat(6, 7, CV_8UC1, a);
    uchar b[6][7] = { { 0,0,0,0,0,0,0 },{ 0,255,255,255,255,0,0 },{ 255,255,255,0,0,0,0 },{ 0,0,0,255,255,0,0 },{ 0,0,0,255,255,0,0 },{ 0,0,0,0,0,0,0 } };
    Mat mask = Mat(6, 7, CV_8UC1, b);

    Mat mat = label&mask;
    mat = mat.reshape(1, 1);
    vector<int> vec;
    mat.row(0).copyTo(vec);
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());

    return 0;
}
#包括
#包括
使用名称空间std;
使用名称空间cv;
int main(){
uchar a[6][7]={0,0,0,0,0,0},{0,1,2,2,3,3,0},{0,0,0,0,0,0,0},{0,5,5,6,6,0,0},{0,5,5,6,0,0},{0,0,0,0,0};
垫标签=垫(6,7,CV_8UC1,a);
uchar b[6][7]={0,0,0,0,0,0},{0255255,0,0},{255255,0,0,0,0,0},{0,0,0255255,0,0,0,0,0},{0,0,02555,0,0,0},{0,0,0,0,0};
Mat掩模=Mat(6,7,CV_8UC1,b);
Mat=标签和面罩;
材料=材料重塑(1,1);
向量向量机;
物料行(0).复制到(vec);
排序(vec.begin(),vec.end());
擦除向量(唯一(vec.begin()、vec.end()、vec.end());
返回0;
}

除了变量名之外,这篇文章非常清楚。我只是想强调,“思考”不是正确的做法。分析你的代码并检查它是否太慢。事实上,我认为这段代码已经达到了它所能达到的速度,因此分析更为必要。请注意,这可能不会像您预期的那样工作,而且如果现在我正确地理解了它,那么还有很大的改进空间。首先澄清一下:矩阵的大小?投资回报率的大小?最大可能标签号?每个图像有多少roi?大小为
5000*188
roi
的大小为
20*10
;每个面具有一个
roi
。@Miki预计会有巨大的改进。也许你的意思是
uchar
只能包含
255
。我们可以使用
Mat-Mat=Mat(标签)和Mat(掩码)这取决于基线(您尚未发布该基线;)。最大可能标签号?标签的数据类型是什么?在你发布的代码中,我没有看到任何投资回报。你是怎么处理的?我分析了你的代码。您问题中的代码运行时间约为1us(微秒!!!),而您答案中的代码运行速度要慢得多,大约为90000us。所以我并没有真正理解你所测量的。除非您提供一个基准作为基线,否则实际上没什么可做的。