我有一个初始起始图像通过一些看起来像这样的处理
我想要做的是填写轮廓,使它看起来像这样
并找到两个(或更多)方块的最佳拟合平行四边形,这样可以让我得到这四条边界线中的每一条
如果有人能指出正确的功能会有所帮助,但我找不到任何有用的东西。我尝试了许多扭曲的矩形校正器,但却无法使它们起作用。
Heres当前源代码
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javacvtesting;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
/**
*
* @author Arhowk
*/
public class JavaCVTesting {
/**
* @param args the command line arguments
*//*
*/
public static BufferedImage convert(Mat m){
Mat image_tmp = m;
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".png", image_tmp, matOfByte);
byte[] byteArray = matOfByte.toArray();
BufferedImage bufImage = null;
try {
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
} catch (Exception e) {
e.printStackTrace();
}finally{
return bufImage;
}
}
public static Mat convert(BufferedImage i){
BufferedImage image = i;
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
Mat mat = new Mat(image.getHeight(),image.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, data);
return mat;
}
public static void show(BufferedImage i){
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(i)));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat src = Highgui.imread("D:\\0_image.png");
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2HSV);
Mat dest = new Mat();
// Mat dest = new Mat(src.width(), src.height(), src.type());
Core.inRange(src, new Scalar(58,125,0), new Scalar(256,256,256), dest);
Mat erode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3));
Mat dilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5));
Imgproc.erode(dest, dest, erode);
Imgproc.erode(dest, dest, erode);
Imgproc.dilate(dest, dest, dilate);
Imgproc.dilate(dest, dest, dilate);
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(dest, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.drawContours(dest, contours, -1, new Scalar(255,255,0));
Panel p = new Panel();
p.setImage(convert(dest));
p.show();
}
}
答案 0 :(得分:8)
要确定外部轮廓,可以使用模式RETR_EXTERNAL的findContours:
List<MatOfPoint> contours = new ArrayList<>();
Mat dest = Mat.zeros(mat.size(), CvType.CV_8UC3);
Scalar white = new Scalar(255, 255, 255));
// Find contours
Imgproc.findContours(image, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Draw contours in dest Mat
Imgproc.drawContours(dest, contours, -1, white);
填写所获得的轮廓:
for (MatOfPoint contour: contours)
Imgproc.fillPoly(dest, Arrays.asList(contour), white);
为每个轮廓找到最合适的矩形:
Scalar green = new Scalar(81, 190, 0);
for (MatOfPoint contour: contours) {
RotatedRect rotatedRect = Imgproc.minAreaRect(new MatOfPoint2f(contour.toArray()));
drawRotatedRect(dest, rotatedRect, green, 4);
}
public static void drawRotatedRect(Mat image, RotatedRect rotatedRect, Scalar color, int thickness) {
Point[] vertices = new Point[4];
rotatedRect.points(vertices);
MatOfPoint points = new MatOfPoint(vertices);
Imgproc.drawContours(image, Arrays.asList(points), -1, color, thickness);
}
答案 1 :(得分:-1)
听起来像你想要floodfill()