OpenCV 工具 ---- 手动调试 HSV的合适的值

OpenCV颜色检测实战:HSV空间与轮廓识别 计算机视觉中的颜色检测是图像处理的基础技术,其核心原理是通过色彩空间转换(如BGR到HSV)分离颜色特征。HSV空间因其对光照变化的鲁棒性,成为颜色识别的首选方案。在工程实践中,结合形态学降噪和轮廓检测技术,可构建稳定的实时检测系统。本项目基于OpenCV实现工业级颜色识别,涉及动态阈调整、形态学操作优化等关键技术,适用于智能监控、工业分拣等场景。通过HSV参数调优和性能优化方案,解决了颜色检测不稳定等典型问题,为计算机视觉入门提供了完整实践路径。 阅读详情
package swing;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

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 utils.Images;

public class Test {
    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}

    private JFrame frame;
    private double[] minHSV = new double[3];
    private double[] maxHSV = new double[3];
    private Size size = new Size();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {



        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test window = new Test();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Test() {
        size = new Size(800, 700);
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        //TODO change image path
        Mat src = Imgcodecs.imread("d:/c/table.png");

        if (src.empty()) {
            System.err.println("Image path is empty!!!");
            return;
        }
        size = src.size();
        Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2HSV);


        frame = new JFrame();
        frame.setBounds(100, 100, 851, 652);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JSlider slider_minH = new JSlider();
        slider_minH.setMaximum(255);
        slider_minH.setBounds(44, 10, 190, 26);
        frame.getContentPane().add(slider_minH);

        JLabel lbl_minH = new JLabel("minH");
        lbl_minH.setFont(new Font("宋体", Font.PLAIN, 14));
        lbl_minH.setBounds(10, 10, 29, 26);
        frame.getContentPane().add(lbl_minH);

        JLabel lbl_showMinH = new JLabel("");
        lbl_showMinH.setBounds(257, 10, 54, 26);
        frame.getContentPane().add(lbl_showMinH);

        JLabel lbl_minS = new JLabel("minS");
        lbl_minS.setFont(new Font("宋体", Font.PLAIN, 14));
        lbl_minS.setBounds(10, 46, 29, 25);
        frame.getContentPane().add(lbl_minS);

        JLabel lbl_showMinS = new JLabel("");
        lbl_showMinS.setBounds(257, 51, 54, 15);
        frame.getContentPane().add(lbl_showMinS);

        JSlider slider_minS = new JSlider();
        slider_minS.setMaximum(255);
        slider_minS.setBounds(44, 46, 190, 26);
        frame.getContentPane().add(slider_minS);

        JLabel lbl_minV = new JLabel("minV");
        lbl_minV.setFont(new Font("宋体", Font.PLAIN, 14));
        lbl_minV.setBounds(10, 81, 29, 27);
        frame.getContentPane().add(lbl_minV);

        JLabel lbl_showMinV = new JLabel("");
        lbl_showMinV.setBounds(257, 87, 54, 15);
        frame.getContentPane().add(lbl_showMinV);

        JSlider slider_minV = new JSlider();
        slider_minV.setMaximum(255);
        slider_minV.setBounds(44, 82, 190, 26);
        frame.getContentPane().add(slider_minV);

        JLabel lbl_img = new JLabel("");
        lbl_img.setBounds(0, 122, (int)size.width, 483);
        frame.getContentPane().add(lbl_img);

        JLabel lbl_maxH = new JLabel("maxH");
        lbl_maxH.setFont(new Font("宋体", Font.PLAIN, 14));
        lbl_maxH.setBounds(364, 16, 54, 15);
        frame.getContentPane().add(lbl_maxH);

        JLabel lbl_showMaxH = new JLabel("");
        lbl_showMaxH.setBounds(656, 16, 54, 15);
        frame.getContentPane().add(lbl_showMaxH);

        JSlider slider_maxH = new JSlider();
        slider_maxH.setMaximum(255);
        slider_maxH.setBounds(446, 10, 200, 26);
        frame.getContentPane().add(slider_maxH);

        JLabel lblMaxs = new JLabel("maxS");
        lblMaxs.setFont(new Font("宋体", Font.PLAIN, 14));
        lblMaxs.setBounds(364, 51, 54, 15);
        frame.getContentPane().add(lblMaxs);

        JLabel lbl_showMaxS = new JLabel("");
        lbl_showMaxS.setBounds(656, 51, 54, 15);
        frame.getContentPane().add(lbl_showMaxS);

        JSlider slider_maxS = new JSlider();
        slider_maxS.setMaximum(255);
        slider_maxS.setBounds(446, 46, 200, 26);
        frame.getContentPane().add(slider_maxS);

        JLabel lblMaxv = new JLabel("maxV");
        lblMaxv.setFont(new Font("宋体", Font.PLAIN, 14));
        lblMaxv.setBounds(364, 87, 54, 15);
        frame.getContentPane().add(lblMaxv);

        JLabel lbl_showMaxV = new JLabel("");
        lbl_showMaxV.setBounds(656, 87, 54, 15);
        frame.getContentPane().add(lbl_showMaxV);

        JSlider slider_maxV = new JSlider();
        slider_maxV.setMaximum(255);
        slider_maxV.setBounds(446, 81, 200, 26);
        frame.getContentPane().add(slider_maxV);


        slider_minH.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                minHSV[0]= slider_minH.getValue();
                lbl_showMinH.setText(slider_minH.getValue()+"");
                Image image = Images.toBufferedImage(processedHSV(src, minHSV, maxHSV));
                lbl_img.setIcon(new ImageIcon(image));

            }
        });

        slider_minS.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                minHSV[1] = slider_minS.getValue();
                lbl_showMinS.setText(slider_minS.getValue()+"");
                Image image = Images.toBufferedImage(processedHSV(src, minHSV, maxHSV));
                lbl_img.setIcon(new ImageIcon(image));
            }
        });

        slider_minV.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                minHSV[2] = slider_minV.getValue();
                lbl_showMinV.setText(slider_minV.getValue()+"");
                Image image = Images.toBufferedImage(processedHSV(src, minHSV, maxHSV));
                lbl_img.setIcon(new ImageIcon(image));
            }
        });

        slider_maxH.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                maxHSV[0] = slider_maxH.getValue();
                lbl_showMaxH.setText(slider_maxH.getValue()+"");
                Image image = Images.toBufferedImage(processedHSV(src, minHSV, maxHSV));
                lbl_img.setIcon(new ImageIcon(image));
            }
        });

        slider_maxS.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                maxHSV[1] = slider_maxS.getValue();
                lbl_showMaxS.setText(slider_maxS.getValue()+"");
                Image image = Images.toBufferedImage(processedHSV(src, minHSV, maxHSV));
                lbl_img.setIcon(new ImageIcon(image));
            }
        });

        slider_maxV.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                maxHSV[2] = slider_maxV.getValue();
                lbl_showMaxV.setText(slider_maxV.getValue()+"");
                Image image = Images.toBufferedImage(processedHSV(src, minHSV, maxHSV));
                lbl_img.setIcon(new ImageIcon(image));
            }
        });
    }

    private Mat processedHSV(Mat input, double[] minHSV, double[] maxHSV) {
        Mat dst = new Mat();
        Core.inRange(input, new Scalar(minHSV), new Scalar(maxHSV), dst);
        return dst;
    }
}
// class Images 的方法
    //转换成为BufferedImage
    public static BufferedImage toBufferedImage(Mat source) {
            //顶一个字节数组矩阵
            MatOfByte mob = new MatOfByte();
            //压缩数据到字节矩阵
            Imgcodecs.imencode(".png", source, mob);
            //将矩阵转数组
            byte[] byteArray =mob.toArray();
           //从数组构建一个输入流
            InputStream input=new ByteArrayInputStream(byteArray);
            //从输入流中读取图像
            try {return ImageIO.read(input);} catch (IOException e) {return null;}
    }

样式:
这里写图片描述
需要OpenCV 环境

从RGB到HSV:搞懂颜色空间转换,让你的OpenCV图像识别更精准 本文深入探讨了HSV颜色空间在OpenCV图像识别中的优势与应用,通过对比RGB与HSV的特性,揭示了HSV在颜色识别中的高准确率(提升73%)。文章提供了从RGB到HSV的转换技巧、HSV获取方法及典型颜色范围参考,帮助开发者实现更精准的图像识别。 阅读详情

相关推荐

基于HSV颜色空间与OpenCV的人民币面识别实践

颜色空间是计算机视觉中用于描述和量化颜色的数学模型,它将颜色信息从直观的RGB表示转换为更符合人类感知或特定任务需求的维度。HSV(色调、饱和度、明度)颜色空间因其将颜色种类(Hue)与光照强度(Value)分离的原理,在物体识别与分割任务中展现出更强的稳定性。这项技术的核心价在于,它允许开发者通过设定颜色阈来提取特定目标,是实现自动化视觉检测的基础方法之一。在工业分拣、机器人引导等应用场景中,基于颜色的初步筛选常作为流程的第一步。本文聚焦于一个具体的工程实践——人民币面识别,详细拆解了如何利用Ope

weixin_30617797的博客 380

hsv封装好的调试工具

hsv封装好的调试工具调试界面: 源码: import cv2 as cv class Hsv_change: #hsv 调试 def __init__(self): self.i1 = 0 self.i2 = 0 self.i3 = 0 self.i4 = 0 self.i5 = 0 ...

苏凯的博客 501

基于HSV颜色空间与轮廓分析的国旗识别:OpenCV传统图像处理实践

在计算机视觉领域,颜色空间转换与轮廓分析是基础且核心的技术。HSV颜色空间将色调、饱和度、明度分离,相比RGB能更稳定地识别颜色,有效克服光照变化的影响。其技术价在于为无需复杂模型训练的场景提供了轻量、快速且可解释性强的解决方案。结合轮廓查找与筛选,可以高效定位具有规则形状和鲜明色块的物体。这一技术组合在图像处理中应用广泛,例如特定标识检测、工业分拣及教育演示。本文以国旗识别为具体应用场景,详细阐述了如何利用HSV分割提取特征色,并通过轮廓的矩形度、宽高比等启发式规则实现目标定位与颜色构成分析,为初学

weixin_34197488的博客 306

Qt制作opencv颜色提取的参数调试工具

Qt制作opencv颜色提取的参数调试工具

龙木南的博客 1422

opencv-python——图片的HSV和RGB滚动条阈分析器

在很多时候,我们需要找到图片的特定通道的阈,就需要通过调整参数来尝试和确定数。如果通过拖动的滚条来调节阈,就可以提高调试效率,缩短试错时间。 文章目录opencv-python的滚动条API创建滑动条——cv2.createTrackbar()获取滑动条的数——cv2.getTrackbar()阈分析器HSV图像阈分析器运行展示RGB颜色分析器运行展示 opencv-python的滚动条API 创建滑动条——cv2.createTrackbar() cv2.createTrackbar(tr.

Irving.Gao的博客 7017

界面方式调试HSV或者RGB颜色范围

import numpy as np import cv2 def nothing(x): pass def mask(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 将捕获的视频帧由RBG转HSV # lower_red = np.array([0, 0, 0]) # upper_red = np.array([255, 255, 255]) lower_red = np.array([20, 1.

wzw12315的专栏 511

调试HSV三个参数

本文参考别人的程序和朋友的帮助下完成的小程序。 通过本程序可以实现ROS下调用ZED相机,去调试HSV三个参数,程序如下: #include<opencv2/core.hpp> #include<opencv2/highgui.hpp> #include<opencv2/imgproc.hpp> #include<ros/ros.h> using n...

yyd__的博客 2283

OpenCV颜色选取工具开发:HSV空间与实时交互

颜色空间转换是计算机视觉中的基础技术,其中HSV(色调、饱和度、亮度)模型因其对颜色信息的解耦特性,成为颜色识别任务的理想选择。通过分离颜色与亮度信息,HSV空间能够有效应对光照变化带来的挑战。在工程实践中,结合OpenCV的图像处理能力和实时交互设计,可以开发出高效的颜色选取工具。这类工具在工业质检、自动驾驶、医学图像处理等领域有广泛应用,特别是需要从复杂背景中提取特定颜色物体的场景。通过轨道条(Trackbar)交互和掩码处理技术,开发者能够实现精确的实时颜色范围选择,为计算机视觉项目提供实用的基础功能

weixin_33895695的博客 377

HSV vs RGB颜色空间对比:OpenCV颜色替换项目中的5个关键差异点

本文深入对比了HSV与RGB颜色空间在OpenCV颜色替换项目中的5个关键差异点,包括色相分离特性、光照鲁棒性、参数直观性、操作复杂度和抗干扰能力。HSV颜色空间凭借其颜色信息分离特性,在颜色替换、图像处理等场景中展现出显著优势,特别是在OpenCV项目中实现更高效、精准的颜色控制。

weixin_30920597的博客 357

OpenCV颜色识别实战:从HSV原理到多颜色动态检测

在计算机视觉中,颜色识别是一项基础且关键的技术,其核心在于如何让计算机像人眼一样稳定地感知颜色。RGB颜色空间因亮度与颜色信息耦合,在光照变化下识别效果不佳。HSV/HSL颜色空间通过解耦色相、饱和度和明度,提供了更鲁棒的解决方案,其中色相(H)决定了颜色种类,受光照影响小。基于阈分割的技术,如OpenCV的cv2.inRange()函数,可将颜色范围转换为二掩膜,是实现颜色识别的关键技术。这项技术的工程价在于其广泛的应用场景,如机器人视觉引导、工业分拣和智能监控。通过动态调参和形态学处理,可以构建适

weixin_33895475的博客 397

鼠标点击来动态确定 HSV 范围

根据鼠标点击来动态确定 HSV 范围,可以先获取用户点击的像素,然后使用这个生成合适HSV 范围。这样,我们可以提取图像中的特定颜色(比如蓝色框)

い天然呆的博客 528

OpenCV色彩空间转换:从RGB到HSV的C++实战指南

色彩空间是描述颜色的数学模型,它通过坐标系和分量来定义颜色。其核心原理在于将颜色信息分解为不同分量,如RGB的加色混合或HSV的色相-饱和度-明度分离。这种分离的技术价在于解耦色度与亮度,使图像处理更高效。在工程实践中,色彩空间转换广泛应用于**颜色阈分割**和**图像预处理**等场景。例如,在目标检测中,转换到HSV空间可以更鲁棒地识别特定颜色区域;在视频压缩中,YCrCb空间的亮度与色度分离能大幅减少数据量。本文聚焦于使用C++和OpenCV实现BGR、灰度、HSV、YCrCb等色彩空间的高效转换,

weixin_42666036的博客 270

别再手动调参了!用OpenCV-Python的滑动条,5分钟搞定图片HSV/RGB阈调试

本文介绍了如何使用OpenCV-Python的滑动条功能快速调试图片的HSV/RGB阈,告别传统手动调参的低效方式。通过实时交互式工具,开发者可以直观调整参数并立即查看效果,大幅提升颜色识别、目标检测等项目的开发效率。文章详细解析了滑动条API的使用方法,并提供了完整的HSV调试器实现方案。

weixin_29879257的博客 354

OpenCV C++颜色匹配实战:从RGB到HSV/Lab,实现鲁棒性图像处理

颜色匹配是计算机视觉与图像处理中的基础且关键的技术,其核心在于让计算机能够准确识别、量化并匹配图像中的颜色信息。其原理通常涉及从原始RGB像素数据出发,通过色彩空间转换(如RGB到HSV或Lab),将颜色信息解耦为色相、饱和度、明度或与人眼感知更一致的色彩分量,从而提升算法对光照变化的鲁棒性。这项技术的价在于,它为更高级的视觉应用提供了可靠的前处理基础,例如在工业自动化中进行产品色差质检,或在互动媒体中实现虚拟物体的颜色融合。本文聚焦于使用OpenCV C++库,深入探讨了包括**HSV色彩空间匹配**和

weixin_29056145的博客 257

OpenCV 颜色检测性能对比:RGB vs HSV 在3种光照场景下的准确率与耗时分析

本文对比了OpenCV中RGB与HSV颜色空间在强光、阴影和混合光三种场景下的颜色检测性能。实验结果显示,HSV模型在光照变化下表现出更高的准确率和稳定性,尽管处理耗时略长。文章还提供了工程实践建议和优化技巧,帮助开发者在计算机视觉项目中做出更优的颜色空间选择。

chuanjiaoye5017的博客 369

python opencv 利用HSV,YUV(YCbCr)实现皮肤检测与抠图,与磨皮美颜

皮肤检测与抠图 皮肤检测的方法很多,这里写的是最简单的方法,感兴趣的同学可以自己加上椭圆检测,膨胀腐蚀等,使得检测与抠图更加精确。github上许多人脸识别的算法,可以多学习那些。 HSV颜色空间 hsv涉及心理学的颜色知识,比rgb检测具有更好的分类效果 python 代码 def get_skin_hsv(img) hsv_img = cv2.cvtColor(img, cv2.COLOR_...

weixin_43379058的博客 4829

OpenCV色彩空间转换实战:从RGB到HSV/YUV/Lab的原理与C++代码详解

色彩空间是描述颜色的数学模型,它将颜色信息映射到特定坐标系中,以便计算机进行处理和分析。其核心原理在于通过不同的分量组合来表征颜色,例如RGB基于红绿蓝三原色的加色模型,而HSV则分离了色相、饱和度和明度,更贴近人类视觉感知。这项技术的价在于能够针对不同视觉任务优化数据表示,提升算法的鲁棒性和效率。在图像处理与计算机视觉领域,色彩空间转换是关键的预处理步骤,广泛应用于目标检测、图像分割、视频压缩和颜色识别等场景。本文聚焦于OpenCV中的cvtColor函数,深入解析BGR、HSV、YUV和Lab等常用色

weixin_33965305的博客 483

OpenCV视频抠图实战:从HSV到背景替换的完整流程

图像分割是计算机视觉的基础任务,其核心原理是根据像素特征将图像划分为不同区域。传统方法通过颜色空间转换(如BGR到HSV)和阈分割,利用颜色或亮度差异分离前景与背景。这项技术在工程实践中价显著,能够实现轻量、高效的实时处理,无需依赖庞大的深度学习模型。其典型应用场景包括绿幕抠像、视频特效制作、证件照背景更换等。本文聚焦于使用OpenCV和NumPy库,详细解析基于HSV颜色空间的色键抠图技术,并涵盖掩膜优化与视频合成的完整实现方案。

weixin_29051149的博客 333
上一篇: OpenCV With Java
下一篇: OpenCV处理图像 --------- 伽马校正
君寻_
博客等级 码龄11年 48粉丝 42原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值