c++ - 如何以最快的方法删除那些指定的标签组件

标签 c++ opencv image-processing

交叉邮寄here

假设我有一个这样的二进制图像

Mat img(1000, 2000, CV_8UC1);
randu(img, Scalar(0), Scalar(255));
inRange(img, Scalar(160), Scalar(200), img);

我将使用 connectedComponentsWithStats 来标记二进制 img

Mat labels, stats, centroids;
int counts_img = connectedComponentsWithStats(img, labels, stats, centroids);

我将指定一些要从 labels 中删除的标签。

vector<int> drop_label(counts_img - 3);
iota(drop_label.begin(), drop_label.end(), 1);

当然我可以用下面的方法来做:

Mat img(1000, 2000, CV_8UC1);
randu(img, Scalar(0), Scalar(255));
inRange(img, Scalar(160), Scalar(200), img);

Mat labels, stats, centroids;
int counts_img = connectedComponentsWithStats(img, labels, stats, centroids);

vector<int> drop_label(counts_img - 3);
iota(drop_label.begin(), drop_label.end(), 1);

//start to count the time.
double start_time = (double)getTickCount();

Mat select = img.clone() = 0;
int img_height = img.rows, img_width = img.cols;
for (int i = 0; i < img_height; i++) {
    int*plabels = labels.ptr<int>(i);
    uchar*pselect = select.ptr<uchar>(i);
    for (int j = 0; j < img_width; j++) {
        if (find(drop_label.begin(), drop_label.end(), plabels[j]) != drop_label.end())
            pselect[j] = 255;
    }
}

Mat result = img - select;

//total time
double total_time = ((double)getTickCount() - start_time) / getTickFrequency();
cout << "total time: " << total_time << "s" << endl;

total time: 96.8676s

如您所见,我确实可以做到,而且据我所知,.ptr 是最快的方法。但我不得不说,我无法忍受函数find 耗费了我那么多时间。任何人都可以告诉我最快的方法吗?

最佳答案

正如 CrisLuengo 的评论 here ,我现在将 99s 增加到 0.004s

Mat img(1000, 2000, CV_8UC1);
randu(img, Scalar(0), Scalar(255));
inRange(img, Scalar(160), Scalar(200), img);

Mat labels, stats, centroids;
int counts_img = connectedComponentsWithStats(img, labels, stats, centroids);

vector<int> drop_label(counts_img - 3);
iota(drop_label.begin(), drop_label.end(), 1);


vector<int> replace_table(counts_img);
iota(replace_table.begin(), replace_table.end(), 0);
for (int i : drop_label)
    replace_table[i] = 0;

//start to count the time.
double start_time = (double)getTickCount();

Mat select = img.clone() = 0;
int img_height = img.rows, img_width = img.cols;
for (int i = 0; i < img_height; i++) {
    int*plabels = labels.ptr<int>(i);
    uchar*pselect = select.ptr<uchar>(i);
    for (int j = 0; j < img_width; j++) {
        if (replace_table[plabels[j]] != 0)
            pselect[j] = 255;
    }
}

Mat result = img - select;

//total time
double total_time = ((double)getTickCount() - start_time) / getTickFrequency();
cout << "total time: " << total_time << "s" << endl;

关于c++ - 如何以最快的方法删除那些指定的标签组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48664698/

相关文章:

c++ - Pre Z 缓冲区通过 OpenGL?

c++ - 加速度计 'Change in Height' 代码 PIC

opencv - 过滤以从文档的彩色图像创建Xerox/影印图像

c - C中图像的负变换

c++ - 自调用递归 lambda 的 std::bad_function_call 但没有提示

opencv - 图像中的圆圈检测

c# - 用一些图案跟踪移动的纸张

Opencv 中的图像质量改进

php - 按建议调整图像大小,直到满足所需的文件大小

android - 什么在 Android 上表现更好?使用 Java 或 C++ 编写的应用程序