基于OpenCV与Java为类方形对象填充颜色的技术求助
我来帮你搞定这个需求!要实现只给类方形区域填充颜色、排除三角形,我们可以结合OpenCV的轮廓分析和形状识别能力,在你现有代码的基础上扩展功能。下面是具体的实现步骤和完整代码:
核心思路
我们需要先从图像里提取所有形状的轮廓,然后通过轮廓的顶点数量区分类方形(4个顶点)和三角形(3个顶点),最后只对类方形区域进行颜色填充。
完整代码实现
import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import java.util.ArrayList; import java.util.List; public class ShapeFill { public static void main(String[] args) { // 加载OpenCV本地库 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 读取原始图像(包含Alpha通道) String imgUrl = "C:\\Users\\me\\Desktop\\cpt\\1.png"; Mat img = Imgcodecs.imread(imgUrl, Imgcodecs.IMREAD_UNCHANGED); if (img.empty()) { System.out.println("无法读取图像!"); return; } // 分离通道,保留Alpha通道用于后续合并 List<Mat> channels = new ArrayList<>(); Core.split(img, channels); Mat alphaChannel = channels.get(3).clone(); // 转为灰度图并二值化,用于提取轮廓 Mat gray = new Mat(); Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGRA2GRAY); Mat binary = new Mat(); Imgproc.threshold(gray, binary, 200, 255, Imgproc.THRESH_BINARY_INV); // 提取所有轮廓 List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); // 创建用于填充的画布(和原图同尺寸的BGRA图) Mat filledImg = Mat.zeros(img.size(), CvType.CV_8UC4); // 遍历每个轮廓,判断形状并填充 for (MatOfPoint contour : contours) { // 计算轮廓的近似多边形(减少顶点数) MatOfPoint2f contour2f = new MatOfPoint2f(contour.toArray()); double epsilon = 0.04 * Imgproc.arcLength(contour2f, true); MatOfPoint2f approx = new MatOfPoint2f(); Imgproc.approxPolyDP(contour2f, approx, epsilon, true); // 转换为Point数组获取顶点数 Point[] points = approx.toArray(); int vertexCount = points.length; // 判断是否为类方形(4个顶点) if (vertexCount == 4) { // 设置填充颜色(这里用红色,你可以改成自己需要的颜色,格式是BGR+Alpha) Scalar fillColor = new Scalar(0, 0, 255, 255); // 填充类方形区域 Imgproc.drawContours(filledImg, List.of(contour), -1, fillColor, Imgproc.FILLED); } } // 合并填充后的图像和原始Alpha通道,保留透明效果 List<Mat> filledChannels = new ArrayList<>(); Core.split(filledImg, filledChannels); filledChannels.set(3, alphaChannel); Mat finalImg = new Mat(); Core.merge(filledChannels, finalImg); // 保存结果 String outputPath = "C:\\Users\\me\\Desktop\\cpt\\1-filled.png"; Imgcodecs.imwrite(outputPath, finalImg); // 释放资源 img.release(); gray.release(); binary.release(); filledImg.release(); finalImg.release(); } }
关键部分解释
- 轮廓近似:
Imgproc.approxPolyDP通过指定的精度参数,把复杂轮廓简化成少量顶点的多边形,这样我们就能通过顶点数快速区分形状(4个顶点对应类方形,3个对应三角形)。 - 形状判断:直接通过近似后的顶点数判断,简单高效,完全适配你的示例图场景。
- Alpha通道处理:保留原始图像的透明通道,确保填充后的图像和原图的透明效果一致。
- 颜色填充:用
Imgproc.drawContours的FILLED模式,给目标轮廓内部填充指定颜色,你可以随时修改Scalar里的数值来调整颜色(格式是蓝、绿、红、透明度)。
如果你的类方形轮廓边缘比较复杂,可以微调epsilon参数(比如改成0.03或0.05)来优化形状识别的精度哦!
内容的提问来源于stack exchange,提问作者Greeny Clicks
相关产品推荐
相关产品推荐

