Q:

How to make the function can process different type image in OpenCV

Cross post here

I have build two function with different name to drop the specfiy lines from difference Mat object, this is the code:
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;
}

Then I can use it in my main() function like
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;
}

Yes, I made it. but as I know, the Mat can have 7 kinds of depth, such as CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F and CV_64F, So I have to build 7 functions with different name to do such thing?? Can anyone tell me how to use one function to implement it??

A:

You cannot do that with cv::Mat. However, you can use cv::Mat_ and do some templating:
template<typename T>
cv::Mat_<T> drop_rows_int(cv::Mat_ mat, vector<int> v) {
...
}

And here you extract pointers of type T.
Just a piece of advice, for efficiency purposes I suggest sending the vector v as a const reference, if possible.

Here is the full solution:
#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;
}

Note that it works only for Mat_, not for Mat.

