在 Java 绑定中循环遍历 OpenCV Mat

Posted

技术标签:

【中文标题】在 Java 绑定中循环遍历 OpenCV Mat【英文标题】:Looping through OpenCV Mat in Java bindings 【发布时间】:2013-03-30 17:48:03 【问题描述】:

我正在尝试将 C++ 方法从使用 OpenCV 收到的 previous answer 转换为使用 OpenCV Java 绑定的 Java

C++ 代码:

cv::Mat gray;
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS,
                                       cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),
                                       cv::Point(erosion_size, erosion_size) );
cv::erode(gray, gray, element);
 // Scan the image searching for points and store them in a vector
std::vector<cv::Point> points;
cv::Mat_<uchar>::iterator it = gray.begin<uchar>();
cv::Mat_<uchar>::iterator end = gray.end<uchar>();
for (; it != end; it++)

    if (*it) 
        points.push_back(it.pos()); 

我不知道如何像在 C 代码中那样循环遍历 gray 变量。以下是我目前得到的:

Java 代码:

Mat gray = new Mat();
Mat element = Imgproc.getStructuringElement(
                Imgproc.MORPH_CROSS, new Size(2 * erosion_size + 1, 2 * erosion_size + 1), new Point(erosion_size, erosion_size)
        );
Imgproc.erode(img, gray, element);
List <Point> p = new ArrayList<Point>();
//How to loop through the gray variable?

我查看了API's,似乎Mat 确实有获取rowscols 的方法,但我无法在任何事情上调用Iterator..

【问题讨论】:

就像我之前告诉你的,使用 JavaCV。 @syb0rg 看起来您之前删除了答案。不要被否决票吓到。它伴随着领土。 @DrewDormann 我没有被吓到,它被否决了,另一个答案被接受了,这意味着 OP 没有听我的建议。如果他们愿意的话,这会让他们的生活变得更轻松...... @syb0rg 我在 JavaCV 的路线上尝试了袍子,但是它没有我想要的一些方法。例如getStructuringElement。也许他们对该方法有不同的名称,但我找不到它。在经历了那种痛苦之后,我决定尝试一下 OpenCV java 绑定,因为它们至少与 C 函数有 1 对 1 的匹配。 【参考方案1】:

如果Mat 真的是灰色,它可能是CV_8U 类型:

for (int i = 0; i < gray.rows; i++)

    for (int j = 0; j < gray.cols; j++)
    
        byte pixel = gray.get(i, j);
    

我没有设置环境来测试此代码。更多信息请查看this thread。

如果你使用 JavaCV,前段时间我写了一个代码来迭代彩色图像的像素并将其转换为灰度,如下所示:

    IplImage imageSrc = cvLoadImage("pipeline.png", CV_LOAD_IMAGE_COLOR);
    if (imageSrc == null) 
    
        System.out.println("!!! Failed loading image");
        return;
    

    double r, g, b;
    r = g = b = 0.0;               

    IplImage imageDst = IplImage.create(imageSrc.width(), imageSrc.height(), IPL_DEPTH_8U, 3);

    CvMat imagePixels = CvMat.createHeader(imageDst.height(), imageDst.width(), CV_32FC1);  
    cvGetMat(imageDst, imagePixels, null, 0); 
    int x, y;
    for(y=0; y<imageSrc.height(); y++)
       for(x=0; x<imageSrc.width(); x++)
       
            CvScalar rgb = cvGet2D(imagePixels, y, x);
            r = rgb.val(0);
            g = rgb.val(2);
            b = rgb.val(1);

            double gray = (r + g + b) / 3;

            CvScalar scalar = new CvScalar();
            scalar.setVal(0, gray);
            scalar.setVal(1, gray);
            scalar.setVal(2, gray);
           cvSet2D(imagePixels, y, x, scalar);
       
       imageDst = new IplImage(imagePixels);  

       IplImage result = new IplImage(imagePixels); 
       cvSaveImage("manual_gray.png", result);

       cvReleaseImage(imageSrc); 

【讨论】:

@karlphillip 你能检查一下这个问题吗***.com/questions/29204124/… 类似于这个。

以上是关于在 Java 绑定中循环遍历 OpenCV Mat的主要内容,如果未能解决你的问题,请参考以下文章

opencv::Mat,从原始数据中获取像素值?

【OPENCV】cv::Mat像素遍历方法比较

opencv中Mat类型数据操作与遍历

OpenCV中高效的像素遍历方法,写出工程级像素遍历代码

行优先与列优先遍历opencv中Mat数据类型的效率差异

OpenCV学习C++接口 Mat像素遍历详解