OpenCV——图像基本操作(三)

一、图像的拼接

//水平拼接
void Core.hconcat(List<Mat> src, Mat dst)
  • src:输入矩阵或矩阵向量,所有的矩阵必须具有相同的行数和相同的深度
  • dst:输出矩阵,和src具有相同的行数和深度,列数等于src列数之和
//垂直拼接
void Core.cvoncat(List<Mat> src, Mat dst)
  • src:输入矩阵或矩阵向量,所有的矩阵必须具有相同的行数和相同的深度
  • dst:输出矩阵,和src具有相同的行数和深度,行数等于src行数之和
public class Concat {
    static {
        OpenCV.loadLocally(); // 自动下载并加载本地库
    }

    public static void main(String[] args) {
        //读取图像并克隆
        Mat src1 = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/church.png");
        Mat src2 = src1.clone();
        //hConcat函数需要的参数准备
        List<Mat> mat1 = new ArrayList<>();
        mat1.add(src1);
        mat1.add(src2);
        //水平拼接
        Mat dst = new Mat();
        Core.hconcat(mat1, dst);
        //显示
        HighGui.imshow("hconcat", dst);
        HighGui.waitKey(0);

        //读取图像并克隆
        Mat src3 = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/leaf.png");
        Mat src4 = src3.clone();
        //vConcat函数需要的参数准备
        List<Mat> mat2 = new ArrayList<>();
        mat2.add(src3);
        mat2.add(src4);
        //垂直拼接
        Mat dst2 = new Mat();
        Core.vconcat(mat2, dst2);
        HighGui.imshow("vconcat", dst2);
        HighGui.waitKey(0);

        System.exit(0);
    }
}

水平拼接:
在这里插入图片描述

垂直拼接:
在这里插入图片描述

二、子矩阵

有时原图非常大,而我们只对图像的一个区域感兴趣,此时可以通过子矩阵来处理。子矩阵是指矩阵的一个子区域,可以像矩阵一样进行处理,但是对子矩阵的任何修改都会同时影响原来的矩阵。

Mat Mat.submat(int rowStart, int rowEnd, int colStart, int colEnd)
  • rowStart:子矩阵在原矩阵中的起始行
  • rowEnd:子矩阵在原矩阵中的终止行
  • colStart:子矩阵在原矩阵中的起始列
  • colEnd:子矩阵在原矩阵中的终止列
Mat Mat.submat(Range rowRange, Range colRange)
  • rowRange:子矩阵行的范围
  • colRange:子矩阵列的范围
Mat Mat.submat(Rect roi)
  • roi:子矩阵的矩形区域
public class Submat {

    static {
        OpenCV.loadLocally(); // 自动下载并加载本地库
    }
    public static void main(String[] args) {
        //读取图像1并显示
        Mat src1 = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/butterfly.png");
        HighGui.imshow("src1", src1);
        HighGui.waitKey(0);
        //创建子矩阵并设置为蓝色
        Mat sub1 = src1.submat(380, 600, 350, 610);
        Scalar blue = new Scalar(255, 0, 0);
        sub1.setTo(blue);
        //显示子矩阵1
        HighGui.imshow("设置子矩阵后的图像1", src1);
        HighGui.waitKey(0);

        //读取图像2并显示
        Mat src2 = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/fish.png");
        HighGui.imshow("src2", src2);
        HighGui.waitKey(0);
        //设置子矩阵
        Rect roi = new Rect(400, 40, 260, 210);
        Mat sub2 = src2.submat(roi);
        //将子矩阵中RGB颜色改为原来的一半
        for (int i = 0; i < sub2.rows(); i++) {
            for (int j = 0; j < sub2.cols(); j++) {
                byte[] data = new byte[3];
                sub2.get(i, j, data);
                for (int n = 0; n < data.length; n++) {
                    data[n] = (byte)(data[n] / 2);
                }
                sub2.put(i, j, data);
            }
        }
        //显示子矩阵
        HighGui.imshow("子矩阵2", sub2);
        HighGui.waitKey(0);
        //显示设置子矩阵后的图像2
        HighGui.imshow("设置子矩阵后的图像2", src2);
        HighGui.waitKey(0);

        //读取图像3
        Mat src3 = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/fish.png");
        //创建子矩阵并设置为蓝色
        Mat sub3 = src3.submat(new Range(400, 600), new Range(450, 800));
        sub3.setTo(blue);
        //显示设置子矩阵后的图像3
        HighGui.imshow("设置子矩阵后的图像3", src3);
        HighGui.waitKey(0);

        //查看3个子矩阵信息
        System.out.println(sub1);
        System.out.println(sub2);
        System.out.println(sub3);
        System.exit(0);

    }
}

原图像1:

在这里插入图片描述
设置子矩阵后的图像1:
在这里插入图片描述

图像2:
在这里插入图片描述

子矩阵:
在这里插入图片描述
设置子矩阵后的图像2:
在这里插入图片描述

设置子矩阵后的图像3:
在这里插入图片描述

三、掩膜

掩膜是指用选定的图像、图形或物体对需要处理的图像进行遮挡来控制处理区域或处理过程。OpenCV中有不少函数支持掩膜操作,这些函数都有mask这个参数。

public class Mask {

    static {
        OpenCV.loadLocally(); // 自动下载并加载本地库
    }
    public static void main(String[] args) {
        //读取图像并显示
        Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/fish.png");
        HighGui.imshow("src", src);
        HighGui.waitKey(0);
        //创建掩膜图像
        Mat mask;
        Scalar black = new Scalar(0, 0, 0);
        Scalar white = new Scalar(255, 255, 255);
        mask = new Mat(src.size(), src.type(), black);
        //定义掩膜区域(矩形区域,白色)
        Rect roi = new Rect(400, 400, 400, 200);
        Mat sub = mask.submat(roi);
        sub.setTo(white);
        //在屏幕上显示掩膜图像
        HighGui.imshow("mask", mask);
        HighGui.waitKey(0);
        //生成带有掩膜的图像并显示
        Mat dst = new Mat(src.size(), src.type(), black);
        src.copyTo(dst, mask);
        HighGui.imshow("dst", dst);
        HighGui.waitKey(0);
        System.exit(0);
    }
}

原图:
在这里插入图片描述

掩膜:
在这里插入图片描述

掩膜后图像:

在这里插入图片描述

### OpenCV 中的图像掩码操作 #### 创建掩码 为了执行有效的图像掩码操作,创建合适的掩码至关重要。通常情况下,掩码是一个灰度图(即单通道),其中白色区域代表要保留的部分,黑色部分则被忽略。 ```python import numpy as np import cv2 # 假设有一个彩色图片 img 和一个形状相同的全黑背景上的圆形白区作为 mask img = cv2.imread('image.jpg') mask = np.zeros(img.shape[:2], dtype=np.uint8) # 绘制圆圈在 mask 上 (中心坐标, 半径, 颜色(255), 线条粗细(-1 表示填充)) cv2.circle(mask, (center_x, center_y), radius, 255, -1) ``` #### 应用掩码于图像上 当有了适当构建好的掩码之后,可以利用 `bitwise_and` 函数来应用这个掩码到原始图像上去。这会使得只有那些对应位置为白色的像素得以保存下来;而其他地方将会变成完全透明或黑色取决于具体应用场景[^1]。 ```python masked_img = cv2.bitwise_and(img, img, mask=mask) ``` 对于某些特定需求来说,可能还需要计算带有掩码条件下的统计特征比如平均亮度等: ```python mean_val_inside_mask = cv2.mean(img, mask)[0] print(f"The mean intensity inside the masked area is {mean_val_inside_mask}") ``` 这里使用了 `cv2.mean()` 方法并传入了一个额外参数 `mask` 来指定只对感兴趣区域内做均值运算[^2]。 另外,在处理不同类型的逻辑运算时也可以通过类似的接口实现,例如取反操作可以通过如下方式完成: ```python inverted_masked_img = cv2.bitwise_not(masked_img) ``` 值得注意的是,如果尝试在一个多通道图像与另一个具有相同尺寸但是仅含单一颜色平面的数据结构之间直接相乘,则可能会遇到错误提示因为它们并不兼容。因此务必确保参与运算的对象都处于同一维度下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值