Java OpenCV使用非COLOR_RGB2GRAY方法实现彩色图像灰度化的问题
问题解答
Core.inRange无法生成灰度图的原因
Core.inRange 是专门用于生成二值掩码的API:仅会将落在指定标量范围内的像素赋值为255,范围外的像素赋值为0,输出结果天生只有两个灰度级,不可能输出包含多阶灰度的正常灰度图像,因此无需再尝试基于该接口实现灰度转换需求。
无需调用Imgproc.cvtColor的灰度转换实现方案
方法1:标准人眼感知加权法(与官方
COLOR_RGB2GRAY转换效果完全一致)
基于人眼对三原色的感知敏感度差异,使用固定权重加权求和得到灰度值,公式如下:灰度值 = 0.299 * R通道值 + 0.587 * G通道值 + 0.114 * B通道值
Java代码实现:// 拆分彩色图的RGB三个通道 List<Mat> rgbChannels = new ArrayList<>(); Core.split(colorPhoto, rgbChannels); // 按权重叠加通道得到灰度图 Mat grayscalePhoto = new Mat(); Core.addWeighted(rgbChannels.get(0), 0.299, rgbChannels.get(1), 0.587, 0, grayscalePhoto); Core.addWeighted(grayscalePhoto, 1, rgbChannels.get(2), 0.114, 0, grayscalePhoto);方法2:三通道平均值法(实现最简,适合低精度场景)
直接对三通道像素取平均值作为灰度值,计算速度最快,公式如下:灰度值 = (R通道值 + G通道值 + B通道值) / 3
Java代码实现:List<Mat> rgbChannels = new ArrayList<>(); Core.split(colorPhoto, rgbChannels); Mat grayscalePhoto = new Mat(); Core.add(rgbChannels.get(0), rgbChannels.get(1), grayscalePhoto); Core.add(grayscalePhoto, rgbChannels.get(2), grayscalePhoto); Core.divide(grayscalePhoto, new Scalar(3.0), grayscalePhoto);方法3:基于直方图的自适应灰度转换
如果需要优化灰度图的对比度适配当前图像的像素分布,可以先通过上述两种方法得到基础灰度图后,叠加直方图均衡化操作:// 基础灰度转换完成后执行均衡化 Imgproc.equalizeHist(grayscalePhoto, grayscalePhoto);如果需要自定义灰度映射规则,可以先统计原图的三通道联合直方图生成自定义灰度映射表,再通过
Core.LUT接口批量映射所有像素得到定制效果的灰度图。
内容的提问来源于stack exchange,提问作者Oliwier Piasecki
相关产品推荐
相关产品推荐

