快速了解opencv进行颜色分割替换

1.前言

写这篇主要是对上篇(关于opencv提取表格的方式总结)添加一点最近学到的也可以先通过颜色进行分割提取,但是也存在一些干扰因素。

opencv中的颜色说下我的理解通常表示颜色的有两种方式RGBGR/RGB/HSV基础标识的,还有我们处理过程中首先要转换用的gray(灰色)。

分割、替换可以理解为抠图,说的是图片有不同的颜色组成我们可以对图片中进行颜色过滤得到想要的颜色部分就进行了过滤(主要用于信息提取),或者对这部分颜色替换为别的颜色(很久前写的一篇文章 Java调用opencv证件照替换背景色 现在都用深度学习替换了)因为手工处理有很多问题不通用还有边缘的锯齿感,这时候有点理解了拍电影常说的绿幕。

2.RGBGR/RGB/gray(灰色)

RGB基础是RED(红色)、GREEN(绿色)、BLUE(蓝色)三色组成各种颜色的,每个像素点上的颜色标识的时候会有个长度为3的数组标识的,每个值的大小是0-255。gray(灰色)是一个值表示的0-255

java 复制代码
Imgproc.cvtColor(clone,clone,Imgproc.COLOR_BGR2GRAY);

RGB值和灰度的转换,实际上是人眼对于彩色的感觉到亮度感觉的转换,这是一个心理学问题,有一个公式:
Grey = 0.299*R + 0.587*G + 0.114*B

3.例子

证件照内容识别。首先得到色彩拆分然后过滤。

ini 复制代码
public static void split(String path){
    Mat src=Imgcodecs.imread(path);
    List<Mat> channels = new ArrayList<>();
    Core.split(src, channels);
    Mat b = channels.get(0);  // 蓝色通道
    Mat g = channels.get(1);  // 绿色通道
    Mat r = channels.get(2);  // 红色通道
    HighGui.imshow("一护", b);
    HighGui.waitKey(0);

    HighGui.imshow("一护", g);
    HighGui.waitKey(0);

    HighGui.imshow("一护", r);
    HighGui.waitKey(0);

    Imgproc.GaussianBlur(b, b, new Size(3, 3), 0, 0);
    //单通道进行过滤
    Imgproc.threshold(b, b, 180, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
    HighGui.imshow("一护", b);
    HighGui.waitKey(0);
}

处理后的图像,是不是显示的信息干净多了。

HSV

HSV的标识是通过色相(Hue)、饱和度(Saturation)和亮度(Value)来标识的。与RGB颜色空间相比,HSV颜色空间在某些情况下更符合人类对颜色的认知方式,因此在进行图像识别和处理时,使用HSV颜色空间可能会更加直观和方便。只是颜色范围控制感觉不好处理虽然有范围。

还是上面图片的例子。图片转换为HSV表示后,配合颜色过滤函数后字体是白色的背景是黑色的。后面做了个转换(可以看出图片是一个一个像素点颜色组成的。转化这里意味着你可以自己写点噪点或者对特定位置进行打马赛克就是对像素点的颜色进行修改)。

java 复制代码
Imgproc.cvtColor(src, hsv,Imgproc.COLOR_BGR2HSV);
Core.inRange(hsv,new Scalar(0, 0, 0), new Scalar(180, 255, 50),split);

//得到一张大小相同的空图Scalar(0, 0, 0)表示黑色
Mat dst = new Mat(src.size(), CvType.CV_8UC3, new Scalar(0, 0, 0));
// 将源图像中的白色像素变为黑色
// 对素点进行遍历 对每个像素点进行颜色的标记
for (int i = 0; i < split.rows(); i++) {
    for (int j = 0; j < split.cols(); j++) {
        double[] pixel = split.get(i, j);
        if (pixel[0] == 255) {
            dst.put(i, j, 0, 0, 0);
        } else {
            dst.put(i, j, 255,255,255);
        }
    }
}
相关推荐
增量星球2 小时前
《持续交付2.0系列一》从技术交付到业务引领
java·docker·容器·devops
Mr__Miss3 小时前
Java 随机数生成器选型指南:Random、ThreadLocalRandom 与 SecureRandom
java·开发语言·python
Wang's Blog3 小时前
Go-Zero基础入门5: 探究go-zero如何基于gRPC扩展客户端
开发语言·后端·golang·go-zero
if_you_can_please_do3 小时前
IDEA插件Maven开发版本管理小助手Maven With Me更新2.9.x版本啦,升版、快速搜索依赖、JDK切换等核心功能助力中大厂业务快速开发与迭代!
java·maven·intellij-idea
zzz_23683 小时前
【Java实习面试算法冲刺】动态规划
java·算法·面试
小堂子这厢有礼了3 小时前
Chet.QuartzNet.UI v2.3.0 大更新!表格重构 + 系统配置 + 分析页全面升级!
前端·后端·ui·重构·c#·vue
cfm_29143 小时前
SpringBoot自定义Starter
java·spring boot·后端
触底反弹3 小时前
⚡ Promise.all 性能优化:让 Agent 的工具调用飞起来
javascript·人工智能·后端
程序员爱钓鱼3 小时前
Rust 控制流 if 详解:条件判断与 if 表达式
前端·后端·rust
Demon_Hao3 小时前
Spring Boot 4、JDK 25 与 GraalVM:Java 云原生进化,能否撼动 Go 的地位?
java·spring boot·云原生