Java+OpenCV获取图片像素颜色后判断颜色大类进行图片总体色调、色系主题分析

接上篇文章:获取像素颜色之后,判断改颜色为哪种颜色大类, 方便进行图片总体色系、色调主题的分析。

如何获取图片像素的Scalar颜色参考上篇文章:Java + OpenCV 读取图片文件的所有像素颜色以及该颜色所有像素数
package com.polar.core.bdata.util;

import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.*;

/**
 * 描述: 判断像素颜色所属大类
 * 作者:过路云野
 * 创建时间:2023/8/29 10:23
 */
public class ColorExtractionTool {
    public static void main(String[] args) {
        // 定义一个颜色 绿色
        Scalar scalarColor = new Scalar( 255, 255, 0 );
        // 转为HSL颜色空间
        double[] color = rgbToHSL(scalarColor);
        // 判断改颜色属于哪个颜色大类
        String colorSeries = getColorSeries(color);
        System.out.println("---------所属颜色大类-----------" + colorSeries);
    }

    /**
     * rgb颜色转HSL
     * @param rgbColor rgb颜色
     * @return HSL
     */
    public static double[] rgbToHSL(Scalar rgbColor) {
        double[] hslColor = new double[3];

        double r = rgbColor.val[0] / 255.0;
        double g = rgbColor.val[1] / 255.0;
        double b = rgbColor.val[2] / 255.0;

        double max = Math.max(r, Math.max(g, b));
        double min = Math.min(r, Math.min(g, b));
        double h, s, l;

        // 计算H值
        if (max == min) {
            h = 0; // 无色
        } else if (max == r) {
            // 红色系
            h = (60 * ((g - b) / (max - min)) + 360) % 360;
        } else if (max == g) {
            // 绿色系
            h = (60 * ((b - r) / (max - min)) + 120) % 360;
        } else {
            // 蓝色系
            h = (60 * ((r - g) / (max - min)) + 240) % 360;
        }

        // 计算L值
        l = (max + min) / 2;

        // 计算S值
        if (max == min) {
            s = 0; // 无饱和度
        } else if (l <= 0.5) {
            s = (max - min) / (2 * l);
        } else {
            s = (max - min) / (2 - 2 * l);
        }
        // 将HSL值转换为0-100的范围
        hslColor[0] = h;
        hslColor[1] = s * 100;
        hslColor[2] = l * 100;

        return hslColor;
    }

    /**
     * 获取颜色色系
     * @param hslColor HSL
     * @return 色系
     */
    public static String getColorSeries(double[] hslColor) {
        double h = hslColor[0];
        double s = hslColor[1];
        double l = hslColor[2];
        if (l < 15) {
            return "黑色";
        } else if (l > 85 && s < 15) {
            return "白色";
        } else if ((l > 15 && l < 65) && s < 15) {
            return "灰色";
        } else if (h >= 330 || h < 30) {
            return "红色";
        } else if (h >= 30 && h < 90) {
            return "黄色";
        } else if (h >= 90 && h < 165) {
            return "绿色";
        } else if (h >= 165 && h < 270) {
            return "蓝色";
        } else if (h >= 270 && h < 320) {
            return "紫色";
        } else if (h >= 320 && h < 330) {
            return "粉色";
        } else {
            return "-未知颜色-";
        }
    }
}

输出结果如下:
---------所属颜色大类-----------黄色

最后可根据结果进行图片色系、颜色主题的分析处理。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现这个功能,你需要使用 JavaOpenCV 库。下面是一个简单的步骤: 1. 导入 OpenCV 库 ```java import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Scalar; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; ``` 2. 加载图片 ```java Mat image = Imgcodecs.imread("path/to/image.jpg"); ``` 3. 将图像转换为 HSV 颜色空间 ```java Mat hsvImage = new Mat(); Imgproc.cvtColor(image, hsvImage, Imgproc.COLOR_BGR2HSV); ``` 4. 用 inRange 函数获取红色区域的二值图像 ```java Mat redMask = new Mat(); Scalar lowerRed = new Scalar(0, 100, 100); Scalar upperRed = new Scalar(10, 255, 255); Core.inRange(hsvImage, lowerRed, upperRed, redMask); ``` 5. 对二值图像进行形态学操作,去掉噪点 ```java Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)); Imgproc.morphologyEx(redMask, redMask, Imgproc.MORPH_OPEN, kernel); Imgproc.morphologyEx(redMask, redMask, Imgproc.MORPH_CLOSE, kernel); ``` 6. 用 findContours 函数获取红色区域的轮廓 ```java List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(redMask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); ``` 7. 用 drawContours 函数将轮廓连接起来 ```java Imgproc.drawContours(image, contours, -1, new Scalar(0, 0, 255), 2); ``` 完整的代码示例: ```java import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Scalar; import org.opencv.core.Size; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.core.MatOfPoint; import java.util.ArrayList; import java.util.List; public class Main { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } public static void main(String[] args) { Mat image = Imgcodecs.imread("path/to/image.jpg"); Mat hsvImage = new Mat(); Imgproc.cvtColor(image, hsvImage, Imgproc.COLOR_BGR2HSV); Mat redMask = new Mat(); Scalar lowerRed = new Scalar(0, 100, 100); Scalar upperRed = new Scalar(10, 255, 255); Core.inRange(hsvImage, lowerRed, upperRed, redMask); Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5)); Imgproc.morphologyEx(redMask, redMask, Imgproc.MORPH_OPEN, kernel); Imgproc.morphologyEx(redMask, redMask, Imgproc.MORPH_CLOSE, kernel); List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(redMask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); Imgproc.drawContours(image, contours, -1, new Scalar(0, 0, 255), 2); Imgcodecs.imwrite("path/to/output.jpg", image); } } ``` 这样就可以实现获取图片红色区域,并用线条连接每个区域的功能啦!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值