[英]Fill in and detect contour rectangles in Java OpenCV
我有一個初始起始圖像通過一些看起來像這樣的處理
我想要做的是填寫輪廓,使它看起來像這樣
並找到兩個(或多個)正方形的最佳擬合平行四邊形,這樣我就可以得到四個邊界線中的每一個
如果有人能指出我能提供幫助的正確功能,但我找不到任何有用的東西。 我嘗試了許多扭曲的矩形校正器但無法使它們工作。
繼承人目前的源代碼
/*
* 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();
}
}
要確定外部輪廓,可以使用模式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); }
聽起來像你想要floodfill()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.