Imgproc.floodFill
Imgproc.circle
Imgproc.rectangle
Imgproc.polylines
近似颜色区域的选择。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JRadioButton; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfPoint; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; public class Floodfill extends JFrame { private JLabel imageView; private Mat canvas; public Floodfill(String path) { int width = 512; int height = 512; int bar = 40; JRadioButton polyBtn = new JRadioButton("图形"); polyBtn.setSelected(true); polyBtn.setBounds(15, 10, 70, 25); polyBtn.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { setPolyCanvas(width, height); setIcon(canvas); } }); JRadioButton picBtn = new JRadioButton("图片"); picBtn.setBounds(95, 10, 70, 25); picBtn.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { canvas = Imgcodecs.imread(path); setIcon(canvas); } }); ButtonGroup group = new ButtonGroup(); group.add(polyBtn); group.add(picBtn); imageView = new JLabel(); imageView.setBounds(0, bar, width, height); imageView.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); Point point = new Point(x, y); fill(point); } }); this.setTitle("颜色填充"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(width, height + bar); this.getContentPane().setLayout(null); this.getContentPane().add(polyBtn); this.getContentPane().add(picBtn); this.getContentPane().add(imageView); setPolyCanvas(width, height); setIcon(canvas); } private void fill(Point point) { Mat image = canvas; // 原图像。1通道或3通道,8位或浮点图像 Mat mask = new Mat(50, 50, CvType.CV_8UC1); // 掩模,遮罩。flags中有FLOODFILL_MASK_ONLY时才起作用 mask = new Mat(image.rows() + 2, image.cols() + 2, CvType.CV_8UC1); // 若起作用(flags加了FLOODFILL_MASK_ONLY),须单通道、8位、长和宽上都比image大两个像素点 mask.rows == size.height+2 && mask.cols == size.width+2 in function 'floodFill' Point seedPoint = point; // 算法的起始点。以此点作为参照,拾取其颜色以计算要填充的区域 Scalar newVal = new Scalar(255, 64, 64); // 填充色 Rect rect = new Rect(); // 返回重绘区域的最小绑定矩形 Scalar loDiff = new Scalar(10, 10, 10); // 和参照点比较,颜色值向下的容差,即大于(seedPoint-loDiff)的都选中 Scalar upDiff = new Scalar(20, 20, 20); // 和参照点比较,颜色值向上的容差,即小于(seedPoint+upDiff)的都选中 int flags = 4| Imgproc.FLOODFILL_FIXED_RANGE; // 算法的连通性: // 一个32bit的int类型数据,由3部分组成: 0-7bit表示邻接性(4邻接、8邻接);8-15bit表示mask的填充颜色;16-31bit表示填充模式 // 4,默认,表示填充算法只考虑当前像素水平方向和垂直方向的相邻点,如一个"十"字; // 8,除上述相邻点外,还会包含对角线方向的相邻点,如一个"米"字。 // 4/8,还可以使用竖杠结合如下两个参数控制: // Imgproc.FLOODFILL_FIXED_RANGE,加此参数表示计算像素时,与seedPoint像素进行相关计算;否则就与其相邻像素计算。也就是说,加此参数计算值的范围是浮动的。 // Imgproc.FLOODFILL_MASK_ONLY,加此参数表示不改变原始图像image(即忽略参数newVal),而是填充遮罩图像mask(mask须设置宽高)。 // 例 int flags = 8 | Imgproc.FLOODFILL_MASK_ONLY | Imgproc.FLOODFILL_FIXED_RANGE | (255 << 8); 表示填充mask值为白色,此时UI显示mask才看到效果 setIcon(mask)。 Imgproc.floodFill(image, mask, seedPoint, newVal, rect, loDiff, upDiff, flags); // 泛洪填充算法。类似photoshop的魔棒选择近似颜色的区域 setIcon(image); } private void setPolyCanvas(int width, int height) { canvas = Mat.zeros(height, width, CvType.CV_8UC1); // 单通道(只有灰度信息),每个像素占用8位。 // 圆 Imgproc.circle(canvas, new Point(150, 150), 50, new Scalar(255, 125, 255), 2); // 边框粗细 // 矩形 Imgproc.rectangle(canvas, new Point(290, 60), new Point(450, 150), new Scalar(255, 128, 0), 3); // 多边形 List<Point> polyPointList = new ArrayList<>(); polyPointList.add(new Point(20, 360)); polyPointList.add(new Point(60, 430)); polyPointList.add(new Point(240, 340)); polyPointList.add(new Point(400, 470)); polyPointList.add(new Point(300, 200)); polyPointList.add(new Point(100, 240)); MatOfPoint mp = new MatOfPoint(); mp.fromList(polyPointList); List<MatOfPoint> pts = new ArrayList<>(); pts.add(mp); Imgproc.polylines(canvas, pts, true, new Scalar(256, 64, 128), 3); } private void setIcon(Mat mat) { BufferedImage image = CVUtil.matToBufferedImage(mat); // CVUtil 见 http://www.gaohaiyan.com/3229.html imageView.setIcon(new ImageIcon(image)); } } |
- end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/3308.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设