java - 如何获取 Mat 图像的像素区域

标签 java opencv

我不熟悉将 Opencv 与 Java 结合使用。我有一个 Mat 图像,我正在尝试读取特定区域中的像素,以便稍后我可以循环遍历该区域并确定我正在尝试使用的 HSV CvRect 获取我想要的图像区域的坐标和大小。我如何获得图像的那个区域?

Mat firstImage = Imgcodecs.imread("firstImage.png");
    CvRect topL = new CvRect(firstImage.get(160, 120, 30, 30));

最佳答案

有两种方法:一个一个地读取像素,或者将整个图像的矩形中的所有像素放入java中,然后使用更大的数组。哪一个最好可能取决于 rect 有多大。下面的代码首先将图像的指定矩形部分放入 Java 数组中。

import java.awt.Color;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.highgui.Highgui;

public class OpenCVThing
{
    public static void main(String[] args)
    {
        String opencvpath = System.getProperty("user.dir") + "\\lib\\";
        System.load(opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll");
        // Get the whole rect into smallImg
        Mat firstImage = Highgui.imread("capture.png");
        System.out.println("total pxels:" + firstImage.total());
        // We are getting a column 30 high and 30 wide
        int width = 30;
        int height = 30;
        Rect roi = new Rect(120, 160, width, height);
        Mat smallImg = new Mat(firstImage, roi);
        int channels = smallImg.channels();
        System.out.println("small pixels:" + smallImg.total());
        System.out.println("channels:" + smallImg.channels());
        int totalBytes = (int)(smallImg.total() * smallImg.channels());
        byte buff[] = new byte[totalBytes];
        smallImg.get(0, 0, buff);

        // assuming it's of CV_8UC3 == BGR, 3 byte/pixel
        // Effectively assuming channels = 3
        for (int i=0; i< height; i++)
        {
            // stride is the number of bytes in a row of smallImg
            int stride = channels * width;
            for (int j=0; j<stride; j+=channels)
            {
                int b = buff[(i * stride) + j];
                int g = buff[(i * stride) + j + 1]; 
                int r = buff[(i * stride) + j + 2];
                float[] hsv = new float[3];
                Color.RGBtoHSB(r,g,b,hsv);
                // Do something with the hsv.
                System.out.println("hsv: " + hsv[0]);
            }
        }
    }
}

注意 1:在这种情况下,buff 中的每个字节代表一个像素的三分之一,因为我假设格式为 CV_8UC3。

代码在这个答案的屏幕截图上进行了测试,输出如下:

total pxels:179305
small pixels:900
channels:3
hsv: 0.5833333
hsv: 0.5833333
hsv: 0.5833333
hsv: 0.5833333
hsv: 0.5833333

etc ...

参见 this pagedocs更多细节

关于java - 如何获取 Mat 图像的像素区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42403741/

相关文章:

java - CreateProcess error=2,系统找不到指定的文件

List<Object> 内的 Java 过滤器映射

java - 斯波克。如何模拟java.lang.Class?

c++ - opencv中矩阵的超快中位数(与matlab一样快)

python - 在 python openCV 的网络摄像头视频上选择静态 ROI

java - 如何创建以数据表为可排序项目的列表

java - 将未知的 Java 类型转换为 Rust 类型

c++ - 创建 CvSVM vector 的 vector (数组)

opencv - 在 ubuntu 14.04 LTS 中安装 opencv 2.4.10 时出现未定义的引用错误

python - 使用Open CV断言失败