1. 程式人生 > >Android opencv(四)輪廓檢測

Android opencv(四)輪廓檢測

輪廓檢測函式:
Imgproc. findContours(image, contours, hierarchy, mode, method)
通過輪廓檢測找到面積最大的輪廓並繪製輪廓:

        List<MatOfPoint> contours=new ArrayList<>();
        Imgproc.findContours(blurredImage,contours,new Mat(),Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_SIMPLE);
        double maxVal = 0;
        int
maxValIdx = 0; for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) { double contourArea = Imgproc.contourArea(contours.get(contourIdx)); if (maxVal < contourArea) { maxVal = contourArea; maxValIdx = contourIdx; } } Mat mRgba=new
Mat(); mRgba.create(blurredImage.rows(), blurredImage.cols(), CvType.CV_8UC3); //繪製檢測到的輪廓 Imgproc.drawContours(mRgba, contours, maxAreaIdx, new Scalar(0,255,0), 5);

//通過輪廓檢測獲取4個交點


    public static List<Point> getCornersByContour(Mat imgsource){
        List<MatOfPoint> contours=new
ArrayList<>(); //輪廓檢測 Imgproc.findContours(imgsource,contours,new Mat(),Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_SIMPLE); double maxArea=-1; int maxAreaIdx=-1; MatOfPoint temp_contour=contours.get(0);//假設最大的輪廓在index=0處 MatOfPoint2f approxCurve=new MatOfPoint2f(); for (int idx=0;idx<contours.size();idx++){ temp_contour=contours.get(idx); double contourarea=Imgproc.contourArea(temp_contour); //當前輪廓面積比最大的區域面積大就檢測是否為四邊形 if (contourarea>maxArea){ //檢測contour是否是四邊形 MatOfPoint2f new_mat=new MatOfPoint2f(temp_contour.toArray()); int contourSize= (int) temp_contour.total(); MatOfPoint2f approxCurve_temp=new MatOfPoint2f(); //對影象輪廓點進行多邊形擬合 Imgproc.approxPolyDP(new_mat,approxCurve_temp,contourSize*0.05,true); if (approxCurve_temp.total()==4){ maxArea=contourarea; maxAreaIdx=idx; approxCurve=approxCurve_temp; } } } double[] temp_double=approxCurve.get(0,0); Point point1=new Point(temp_double[0],temp_double[1]); temp_double=approxCurve.get(1,0); Point point2=new Point(temp_double[0],temp_double[1]); temp_double=approxCurve.get(2,0); Point point3=new Point(temp_double[0],temp_double[1]); temp_double=approxCurve.get(3,0); Point point4=new Point(temp_double[0],temp_double[1]); List<Point> source=new ArrayList<>(); source.add(point1); source.add(point2); source.add(point3); source.add(point4); //對4個點進行排序 Point centerPoint=new Point(0,0);//質心 for (Point corner:source){ centerPoint.x+=corner.x; centerPoint.y+=corner.y; } centerPoint.x=centerPoint.x/source.size(); centerPoint.y=centerPoint.y/source.size(); Point lefttop=new Point(); Point righttop=new Point(); Point leftbottom=new Point(); Point rightbottom=new Point(); for (int i=0;i<source.size();i++){ if (source.get(i).x<centerPoint.x&&source.get(i).y<centerPoint.y){ lefttop=source.get(i); }else if (source.get(i).x>centerPoint.x&&source.get(i).y<centerPoint.y){ righttop=source.get(i); }else if (source.get(i).x<centerPoint.x&& source.get(i).y>centerPoint.y){ leftbottom=source.get(i); }else if (source.get(i).x>centerPoint.x&&source.get(i).y>centerPoint.y){ rightbottom=source.get(i); } } source.clear(); source.add(lefttop); source.add(righttop); source.add(leftbottom); source.add(rightbottom); return source; }

ps:輪廓檢測的輸入影象必須是二值化的圖片否則只能檢測一個輪廓。