如何使函数可以在 OpenCV 中处理不同类型的图像

Posted

技术标签:

【中文标题】如何使函数可以在 OpenCV 中处理不同类型的图像【英文标题】:How to make the function can process different type image in OpenCV 【发布时间】:2018-04-02 06:40:44 【问题描述】:

转帖here


我已经构建了两个具有不同名称的函数来从差异Mat 对象中删除规范行,这是代码:

Mat drop_rows_int(Mat mat, vector<int> v) 
    Mat mat_new = Mat::zeros(mat.rows - v.size(), mat.cols, CV_32SC1);
    for (int i = 0, j = 0; i < mat.rows; i++) 
        if (find(v.begin(), v.end(), i) != v.end())
        
            continue;
        
        else
        
            int*pmat = mat.ptr<int>(i);
            int*pmat_new = mat_new.ptr<int>(j);
            for (int w = 0; w < mat.cols; w++) 
                pmat_new[w] = pmat[w];
            
            j++;
        
    
    return mat_new;


Mat drop_rows_uchar(Mat mat, vector<int> v) 
    Mat mat_new = Mat::zeros(mat.rows - v.size(), mat.cols, CV_8UC1);
    for (int i = 0, j = 0; i < mat.rows; i++) 
        if (find(v.begin(), v.end(), i) != v.end())
        
            continue;
        
        else
        
            uchar*pmat = mat.ptr<uchar>(i);
            uchar*pmat_new = mat_new.ptr<uchar>(j);
            for (int w = 0; w < mat.cols; w++) 
                pmat_new[w] = pmat[w];
            
            j++;
        
    
    return mat_new;

然后我可以在我的 main() 函数中使用它

int main()

    Mat mat_uchar = (Mat_<uchar>(5, 4) << 5, 6, 0, 4, 0, 1, 9, 9, 100, 3, 5, 8, 200, 33, 1, 4, 8, 88, 23, 6);
    Mat new_mat_uchar = drop_rows_uchar(mat_uchar, 2,4);

    Mat mat_int = (Mat_<int>(5, 4) << 5, 6, 0, 4, 0, 1, 9, 9, 100, 3, 5, 8, 200, 33, 1, 4, 8, 88, 23, 6);
    Mat new_mat_int = drop_rows_int(mat_int,  2,4 );

        return 0;

是的,我做到了。但是据我所知,Mat可以有7种深度,比如CV_8UCV_8SCV_16UCV_16SCV_32SCV_32FCV_64F,所以我不得不构建 7 个不同名称的函数来做这样的事情?谁能告诉我如何使用一个函数来实现它??

【问题讨论】:

【参考方案1】:

cv::Mat 无法做到这一点。但是,您可以使用cv::Mat_ 并做一些模板:

template<typename T>
cv::Mat_<T> drop_rows_int(cv::Mat_ mat, vector<int> v) 
...

在这里你提取类型 T 的指针。

只是一条建议,为了提高效率,我建议尽可能将向量 v 作为 const 引用发送。


这里是完整的解决方案:

#include "opencv/cv.h"
#include <vector>
#include <iostream>

template<typename T>
cv::Mat_<T> drop_rows(cv::Mat_<T> mat, const std::vector<int> &v) 
    cv::Mat_<T> mat_new = cv::Mat_<T>::zeros(mat.rows - v.size(), mat.cols);
    for (int i = 0, j = 0; i < mat.rows; i++) 
        if (find(v.begin(), v.end(), i) != v.end())
            continue;
        else 
            for (int w = 0; w < mat.cols; w++) 
                mat_new(j, w) = mat(i, w);
            
            j++;
        
    
    return mat_new;


int main() 
    cv::Mat_<uchar> mat = (cv::Mat_<uchar>(5, 4) << 5, 6, 0, 4, 0, 1, 9, 9, 100, 3, 5, 8, 200, 1, 2, 3, 4, 5, 6, 7);
    auto result = drop_rows(mat, 2, 4);

    std::cout << mat << std::endl;;
    std::cout << result << std::endl;;

    return 0;

请注意,它仅适用于Mat_,不适用于Mat

【讨论】:

对不起,我无法完全理解。这是我作为you say 的尝试,你能介意展示一个完整的解决方案吗?但是我运行代码时会得到错误信息 我更新了答案。作为未来的经验法则,永远不要拍照编码。总是 pastebin ;)。

以上是关于如何使函数可以在 OpenCV 中处理不同类型的图像的主要内容,如果未能解决你的问题,请参考以下文章

如何查找opencv中的函数

Arcgis中怎样使不同图斑的公共边界重合?

如何在自己的函数中最好地处理 Mat 中的不同数字格式

Java opencv inRange 阈值函数使我的图像变成三个不同的图像?

Opencv中的阈值函数

opencv中cvScalarAll函数啥意思???