java+opencv4.5.0 实现获取照片所有红色角点。再用线条连接
时间: 2024-05-13 11:18:34 浏览: 152
实现这个功能,可以按照以下步骤进行:
1. 导入 OpenCV Java 库,创建 Mat 对象读取照片。
```java
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat image = Imgcodecs.imread("image.jpg");
```
2. 将图片转换为 HSV 色彩空间,在 HSV 色彩空间中,红色的范围是两个区间:[0,10] 和 [170,180],使用 inRange 函数提取出红色区域。
```java
Mat hsvImage = new Mat();
Imgproc.cvtColor(image, hsvImage, Imgproc.COLOR_BGR2HSV);
Mat redMask1 = new Mat();
Mat redMask2 = new Mat();
Core.inRange(hsvImage, new Scalar(0, 70, 50), new Scalar(10, 255, 255), redMask1);
Core.inRange(hsvImage, new Scalar(170, 70, 50), new Scalar(180, 255, 255), redMask2);
Core.bitwise_or(redMask1, redMask2, redMask);
```
3. 对提取出来的红色区域进行形态学操作,将小的噪点去除,只留下角点。
```java
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
Imgproc.morphologyEx(redMask, redMask, Imgproc.MORPH_CLOSE, kernel);
Mat corners = new Mat();
Imgproc.cornerHarris(redMask, corners, 2, 3, 0.04);
Core.normalize(corners, corners, 0, 255, Core.NORM_MINMAX);
```
4. 在角点位置绘制圆点,并用线条连接所有角点。
```java
for (int i = 0; i < corners.rows(); i++) {
for (int j = 0; j < corners.cols(); j++) {
double[] corner = corners.get(i, j);
if (corner[0] > threshold) {
Imgproc.circle(image, new Point(j, i), 3, new Scalar(0, 255, 0), 2);
cornersList.add(new Point(j, i));
}
}
}
Mat lines = new Mat();
Imgproc.HoughLinesP(redMask, lines, 1, Math.PI / 180, 50, 50, 10);
for (int i = 0; i < lines.rows(); i++) {
double[] line = lines.get(i, 0);
Point pt1 = new Point(line[0], line[1]);
Point pt2 = new Point(line[2], line[3]);
Imgproc.line(image, pt1, pt2, new Scalar(0, 0, 255), 2);
}
```
完整代码如下:
```java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.highgui.HighGui;
import java.util.ArrayList;
import java.util.List;
public class RedCornerDetection {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat image = Imgcodecs.imread("image.jpg");
Mat hsvImage = new Mat();
Imgproc.cvtColor(image, hsvImage, Imgproc.COLOR_BGR2HSV);
Mat redMask1 = new Mat();
Mat redMask2 = new Mat();
Core.inRange(hsvImage, new Scalar(0, 70, 50), new Scalar(10, 255, 255), redMask1);
Core.inRange(hsvImage, new Scalar(170, 70, 50), new Scalar(180, 255, 255), redMask2);
Mat redMask = new Mat();
Core.bitwise_or(redMask1, redMask2, redMask);
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
Imgproc.morphologyEx(redMask, redMask, Imgproc.MORPH_CLOSE, kernel);
Mat corners = new Mat();
Imgproc.cornerHarris(redMask, corners, 2, 3, 0.04);
Core.normalize(corners, corners, 0, 255, Core.NORM_MINMAX);
List<Point> cornersList = new ArrayList<>();
double threshold = 100000;
for (int i = 0; i < corners.rows(); i++) {
for (int j = 0; j < corners.cols(); j++) {
double[] corner = corners.get(i, j);
if (corner[0] > threshold) {
Imgproc.circle(image, new Point(j, i), 3, new Scalar(0, 255, 0), 2);
cornersList.add(new Point(j, i));
}
}
}
Mat lines = new Mat();
Imgproc.HoughLinesP(redMask, lines, 1, Math.PI / 180, 50, 50, 10);
for (int i = 0; i < lines.rows(); i++) {
double[] line = lines.get(i, 0);
Point pt1 = new Point(line[0], line[1]);
Point pt2 = new Point(line[2], line[3]);
Imgproc.line(image, pt1, pt2, new Scalar(0, 0, 255), 2);
}
HighGui.imshow("Red Corner Detection", image);
HighGui.waitKey();
}
}
```
阅读全文