霍夫直线
霍夫直线的原理较为复杂,但其应用广泛,用于在图形转换中检测直线,其声明如下:
HoughLinesP(images, lines, rho, theta, threshold, minLineLength, maxLineGap);
各参数解释如下:
-
images
表示出入图像,8单位通道类型,一般为二值图。 -
ines
表示输出的每个直线的极坐标方程的两个参数。 -
rho
表示极坐标空间r值的每次步长,一般为1. -
theta
表示角度,每次移动1即可。 -
threshold
表示极坐标中该点的累计数,累计值越大,得到的直线可能就越长。一般而言其取值范围为30~50,单位像素,表示大于该值的线段才会被检测到。 -
minLineLength
表示检测的最小线段长度。 -
maxLineGap
表示线段之间的最大间隔值。
Java代码(JavaFX Controller层)
public class Controller{
@FXML private Text fxText;
@FXML private ImageView imageView;
@FXML public void handleButtonEvent(ActionEvent actionEvent) throws IOException {
Node source = (Node) actionEvent.getSource();
Window theStage = source.getScene().getWindow();
FileChooser fileChooser = new FileChooser();
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png");
fileChooser.getExtensionFilters().add(extFilter);
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JPG Files(*.jpg)", "*.jpg"));
File file = fileChooser.showOpenDialog(theStage);
runInSubThread(file.getPath());
}
private void runInSubThread(String filePath){
new Thread(new Runnable() {
@Override
public void run() {
try {
WritableImage writableImage = houghLinesP(filePath);
Platform.runLater(new Runnable() {
@Override
public void run() {
imageView.setImage(writableImage);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private WritableImage houghLinesP(String filePath) throws IOException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat src = Imgcodecs.imread(filePath);
Mat dst = new Mat();
Mat edges = new Mat();
Imgproc.Canny(src, edges, 50, 150,3, true);
Mat lines = new Mat();
Imgproc.HoughLinesP(edges, lines, 1, (Math.PI / 180), 100, 50, 10);
Mat out = Mat.zeros(src.size(), src.type());
for (int i = 0; i < lines.rows(); i++) {
int[] one_line = new int[4];
lines.get(i, 0, one_line);
Imgproc.line(out, new Point(one_line[0], one_line[1]), new Point(one_line[2], one_line[3])
,new Scalar(0,0,255), 2,8,0);
}
out.copyTo(dst);
MatOfByte matOfByte = new MatOfByte();
Imgcodecs.imencode(".jpg", dst, matOfByte);
byte[] bytes = matOfByte.toArray();
InputStream in = new ByteArrayInputStream(bytes);
BufferedImage bufImage = ImageIO.read(in);
WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
return writableImage;
}
}
运行图
原图