public static int san_Num=0,rect_Num=0,lin_Num=0,star_Num=0,yuan_Num=0;
public static Mat shapeDetect(Mat result) {
san_Num = 0;
rect_Num = 0;
lin_Num = 0;
star_Num = 0;
yuan_Num = 0;
//#使用自适应阈值分割
Mat grayImage = new Mat();
Imgproc.cvtColor(result, grayImage, Imgproc.COLOR_BGR2GRAY);
Mat edges = new Mat();
Mat canny_all_hierarchy = new Mat();
Mat edge1=new Mat();
try {
Mat canny_new_img = result.clone();
Imgproc.GaussianBlur(grayImage, grayImage, new Size(3, 3), 0, 0, Core.BORDER_DEFAULT);
Imgproc.threshold(grayImage, edges, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);
List<MatOfPoint> canny_all_contours = new ArrayList<MatOfPoint>();
Core.bitwise_not(edges, edges);
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)); // 指定腐蚀膨胀核
Imgproc.dilate(edges, edges, kernel);
Imgproc.dilate(edges, edges, kernel);
Imgproc.findContours(edges, canny_all_contours, canny_all_hierarchy,
Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
//边缘化之后再查找所有的轮廓
edge1 = edges.clone();
for (MatOfPoint c : canny_all_contours) {
int area = 0;
area = (int) Imgproc.contourArea(c);
Log.i("ShapeDetect", "识别面积:" + area);
//300、800、500 if (area > 500&&800<area)
double peri = Imgproc.arcLength(new MatOfPoint2f(c.toArray()), true);
Log.i("ShapeDetect", "识别周长:" + peri);
if (area > 50 && area < 6000) {
DetectShape(new MatOfPoint2f(c.toArray()));//统计形状个数
}
}
Log.e("Shape", "三角形个数:" + san_Num + "矩形个数:" + rect_Num + "菱形个数:" + lin_Num
+ "五角形个数:" + star_Num + "圆形个数:" + yuan_Num + "个数" + canny_all_contours.size());
}catch (Exception e){
}
return edge1;
}
识别
private static void DetectShape (MatOfPoint2f c){
int area = 0;
area = (int) Imgproc.contourArea(c);
String shape = "";
//计算轮廓的周长
double peri = Imgproc.arcLength(c, true);
if (area > 100 && area < 7000) {
double side_lenght = peri / 4;//计算出菱形或者正方形的边长,用于判断菱形与正方形和矩形的区别
MatOfPoint2f approx = new MatOfPoint2f();
//得到大概值
Imgproc.approxPolyDP(c, approx, 0.04* peri, true);
int s = approx.toList().size();
Log.e("TAG", "大小" + s);
//如果是三角形形状,则有三个顶点
if (approx.toList().size() == 3) {
san_Num++;
shape = "triangle";
}
//如果有四个顶点,则是正方形或者长方形
else if (approx.toList().size() == 4) {
double area1 = 0, minArea = 0;
area1 = Imgproc.contourArea(c);
RotatedRect rect1 = Imgproc.minAreaRect(c);
minArea = rect1.size.area();
double rec = area1 / minArea;
if (rec >= 0.83 && rec < 1.15) {
shape = "rectangle";
rect_Num++;
} else {
lin_Num++;
shape = "rhombus";
}
}
//如果是五角形,则有五个顶点
else if (approx.toList().size() >= 10 && approx.toList().size() <= 13) {
shape = "pentagon";
star_Num++;
}
//除了以上情况之外,我们假设为圆形 圆形可用霍夫检测
// else if(approx.toList().size()>13){
else {
yuan_Num++;
shape = "circle";
}
}
}