Example usage for org.opencv.imgproc Imgproc convexHull

List of usage examples for org.opencv.imgproc Imgproc convexHull

Introduction

In this page you can find the example usage for org.opencv.imgproc Imgproc convexHull.

Prototype

public static void convexHull(MatOfPoint points, MatOfInt hull) 

Source Link

Usage

From source file:edu.fiu.cate.breader.BaseSegmentation.java

/**
 * Finds the bounding box for the book on the stand using 
 * the high resolution image./*w ww.  j  av a 2 s .c o  m*/
 * @param src- High Resolution image of the book
 * @return Rectangle delineating the book
 */
public Rect highRes(Mat src) {
    Mat dst = src.clone();
    Imgproc.blur(src, dst, new Size(100.0, 100.0), new Point(-1, -1), Core.BORDER_REPLICATE);
    Imgproc.threshold(dst, dst, 0, 255, Imgproc.THRESH_BINARY_INV + Imgproc.THRESH_OTSU);
    Imgproc.Canny(dst, dst, 50, 200, 3, false);

    List<MatOfPoint> contours = new LinkedList<>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(dst, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE,
            new Point(0, 0));

    Mat color = new Mat();
    Imgproc.cvtColor(src, color, Imgproc.COLOR_GRAY2BGR);
    for (int k = 0; k < contours.size(); k++) {
        byte[] vals = ITools.getHeatMapColor((float) k / (float) contours.size());
        Imgproc.drawContours(color, contours, k, new Scalar(vals[0], vals[1], vals[2]), 8);
    }
    new IViewer("HighRes Contours ", BReaderTools.bufferedImageFromMat(color));

    Point center = new Point(src.cols() / 2, src.rows() / 2);
    //Check hierarchy tree
    int[] res = polySearch(center, hierarchy, contours, 0);
    while (res[0] != 1 && res[2] != -1) {
        res = polySearch(center, hierarchy, contours, res[2]);
        if (res[0] == 1)
            break;
    }

    MatOfInt tHull = new MatOfInt();
    int index = 0;
    if (res[1] != -1) {
        index = res[1];
    }
    Imgproc.convexHull(contours.get(index), tHull);

    //get bounding box
    MatOfPoint cont = contours.get(index);
    Point[] points = new Point[tHull.rows()];
    for (int i = 0; i < tHull.rows(); i++) {
        int pIndex = (int) tHull.get(i, 0)[0];
        points[i] = new Point(cont.get(pIndex, 0));
    }
    Rect out = Imgproc.boundingRect(new MatOfPoint(points));
    return out;
}

From source file:edu.fiu.cate.breader.BaseSegmentation.java

/**
 * Finds the bounding box for the book on the stand using 
 * the depth average image.//from   w ww .  jav a2s . co m
 * @param src- The Depth average image
 * @return Rectangle delineating the book
 */
public Rect lowResDist(Mat src) {
    Mat dst = src.clone();

    Imgproc.blur(src, dst, new Size(5, 5), new Point(-1, -1), Core.BORDER_REPLICATE);
    //      Imgproc.threshold(dst, dst, 0,255,Imgproc.THRESH_BINARY_INV+Imgproc.THRESH_OTSU);
    Imgproc.Canny(dst, dst, 50, 200, 3, false);
    //      Canny(src, dst, 20, 60, 3);

    List<MatOfPoint> contours = new LinkedList<>();
    Mat hierarchy = new Mat();
    /// Find contours
    Imgproc.findContours(dst, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE,
            new Point(0, 0));

    Mat color = new Mat();
    Imgproc.cvtColor(src, color, Imgproc.COLOR_GRAY2BGR);
    for (int k = 0; k < contours.size(); k++) {
        byte[] vals = ITools.getHeatMapColor((float) k / (float) contours.size());
        Imgproc.drawContours(color, contours, k, new Scalar(vals[0], vals[1], vals[2]), 1);
    }
    new IViewer("LowRes Contours ", BReaderTools.bufferedImageFromMat(color));

    for (int k = 0; k < contours.size(); k++) {
        MatOfPoint2f tMat = new MatOfPoint2f();
        Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(k).toArray()), tMat, 5, true);
        contours.set(k, new MatOfPoint(tMat.toArray()));
    }

    List<Point> points = new LinkedList<Point>();
    for (int i = 0; i < contours.size(); i++) {
        points.addAll(contours.get(i).toList());
    }

    MatOfInt tHull = new MatOfInt();
    Imgproc.convexHull(new MatOfPoint(points.toArray(new Point[points.size()])), tHull);

    //get bounding box
    Point[] tHullPoints = new Point[tHull.rows()];
    for (int i = 0; i < tHull.rows(); i++) {
        int pIndex = (int) tHull.get(i, 0)[0];
        tHullPoints[i] = points.get(pIndex);
    }
    Rect out = Imgproc.boundingRect(new MatOfPoint(tHullPoints));
    return out;
}

From source file:logic.featurepointextractor.MouthFPE.java

/**
 * Detect mouth feature points//w ww  .  ja va 2  s.  c o m
 * Algorithm:           Equalize histogram of mouth rect
 *                      Implement Sobel horizontal filter
 *                      Find corners
 *                      Invert color + Binarization
 *                      Find lip up and down points
 * @param mc
 * @return 
 */
@Override
public Point[] detect(MatContainer mc) {
    /**Algorithm
     *                  find pix(i) = (R-G)/R
     *                  normalize: 2arctan(pix(i))/pi
     */

    //find pix(i) = (R-G)/R
    Mat mouthRGBMat = mc.origFrame.submat(mc.mouthRect);
    List mouthSplitChannelsList = new ArrayList<Mat>();
    Core.split(mouthRGBMat, mouthSplitChannelsList);
    //extract R-channel
    Mat mouthR = (Mat) mouthSplitChannelsList.get(2);
    mouthR.convertTo(mouthR, CvType.CV_64FC1);
    //extract G-channel
    Mat mouthG = (Mat) mouthSplitChannelsList.get(1);
    mouthG.convertTo(mouthG, CvType.CV_64FC1);
    //calculate (R-G)/R
    Mat dst = new Mat(mouthR.rows(), mouthR.cols(), CvType.CV_64FC1);
    mc.mouthProcessedMat = new Mat(mouthR.rows(), mouthR.cols(), CvType.CV_64FC1);

    Core.absdiff(mouthR, mouthG, dst);
    //        Core.divide(dst, mouthR, mc.mouthProcessedMat);
    mc.mouthProcessedMat = dst;
    mc.mouthProcessedMat.convertTo(mc.mouthProcessedMat, CvType.CV_8UC1);
    Imgproc.equalizeHist(mc.mouthProcessedMat, mc.mouthProcessedMat);
    //       Imgproc.blur(mc.mouthProcessedMat, mc.mouthProcessedMat, new Size(4,4));
    //        Imgproc.morphologyEx(mc.mouthProcessedMat, mc.mouthProcessedMat, Imgproc.MORPH_OPEN, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(4,4)));
    Imgproc.threshold(mc.mouthProcessedMat, mc.mouthProcessedMat, 230, 255, THRESH_BINARY);

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(mc.mouthProcessedMat, contours, new Mat(), Imgproc.RETR_TREE,
            Imgproc.CHAIN_APPROX_SIMPLE);

    //find the biggest contour
    int maxSize = -1;
    int tmpSize = -1;
    int index = -1;

    Rect centMouthRect = new Rect(mc.mouthRect.x + mc.mouthRect.width / 4,
            mc.mouthRect.y + mc.mouthRect.height / 4, mc.mouthRect.width / 2, mc.mouthRect.height / 2);
    if (contours.size() != 0) {
        maxSize = contours.get(0).toArray().length;
        tmpSize = 0;
        index = 0;
    }

    //find max contour
    for (int j = 0; j < contours.size(); ++j) {
        //if contour is vertical, exclude it 
        Rect boundRect = Imgproc.boundingRect(contours.get(j));
        int centX = mc.mouthRect.x + boundRect.x + boundRect.width / 2;
        int centY = mc.mouthRect.y + boundRect.y + boundRect.height / 2;
        //                LOG.info("Center = " + centX + "; " + centY);
        //                LOG.info("Rect = " + centMouthRect.x + "; " + centMouthRect.y);
        if (!centMouthRect.contains(new Point(centX, centY)))
            continue;

        tmpSize = contours.get(j).toArray().length;

        LOG.info("Contour " + j + "; size = " + tmpSize);

        if (tmpSize > maxSize) {
            maxSize = tmpSize;
            index = j;
        }
    }

    //appproximate curve
    Point[] p1 = contours.get(index).toArray();
    MatOfPoint2f p2 = new MatOfPoint2f(p1);
    MatOfPoint2f p3 = new MatOfPoint2f();
    Imgproc.approxPolyDP(p2, p3, 1, true);

    p1 = p3.toArray();

    MatOfInt tmpMatOfPoint = new MatOfInt();
    Imgproc.convexHull(new MatOfPoint(p1), tmpMatOfPoint);

    Rect boundRect = Imgproc.boundingRect(new MatOfPoint(p1));
    if (boundRect.area() / mc.mouthRect.area() > 0.3)
        return null;

    int size = (int) tmpMatOfPoint.size().height;
    Point[] _p1 = new Point[size];
    int[] a = tmpMatOfPoint.toArray();

    _p1[0] = new Point(p1[a[0]].x + mc.mouthRect.x, p1[a[0]].y + mc.mouthRect.y);
    Core.circle(mc.origFrame, _p1[0], 3, new Scalar(0, 0, 255), -1);
    for (int i = 1; i < size; i++) {
        _p1[i] = new Point(p1[a[i]].x + mc.mouthRect.x, p1[a[i]].y + mc.mouthRect.y);
        Core.circle(mc.origFrame, _p1[i], 3, new Scalar(0, 0, 255), -1);
        Core.line(mc.origFrame, _p1[i - 1], _p1[i], new Scalar(255, 0, 0), 2);
    }
    Core.line(mc.origFrame, _p1[size - 1], _p1[0], new Scalar(255, 0, 0), 2);

    /*        contours.set(index, new MatOfPoint(_p1));
            
            mc.mouthProcessedMat.setTo(new Scalar(0));
                    
            Imgproc.drawContours(mc.mouthProcessedMat, contours, index, new Scalar(255), -1);
                    
    */ mc.mouthMatOfPoint = _p1;

    MatOfPoint matOfPoint = new MatOfPoint(_p1);
    mc.mouthBoundRect = Imgproc.boundingRect(matOfPoint);
    mc.features.mouthBoundRect = mc.mouthBoundRect;

    /**extract feature points:  1 most left
     *                          2 most right
     *                          3,4 up
     *                          5,6 down
     */

    //        mc.mouthMatOfPoint = extractFeaturePoints(contours.get(index));

    return null;
}

From source file:org.usfirst.frc.team2084.CMonster2016.vision.BallProcessor.java

License:Open Source License

@Override
public void process(Mat cameraImage) {
    Imgproc.blur(cameraImage, hsvImage, new Size(20, 20));

    Imgproc.cvtColor(hsvImage, hsvImage, Imgproc.COLOR_BGR2HSV);

    // Threshold image to find blue/green
    Core.inRange(hsvImage, thresholdMin, thresholdMax, thresholdImage);

    Imgproc.erode(thresholdImage, thresholdImage, KERNEL);
    Imgproc.dilate(thresholdImage, thresholdImage, KERNEL);

    thresholdImage.copyTo(contourImage);

    contours.clear();//from  w  w w  . java  2 s. com
    hulls.clear();

    Imgproc.findContours(contourImage, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    Imgproc.drawContours(cameraImage, contours, -1, CONTOUR_COLOR);

    for (int i = 0; i < contours.size(); i++) {
        MatOfPoint contour = contours.get(i);
        MatOfInt hullIndices = new MatOfInt();
        MatOfPoint hull;
        hulls.add(hull = new MatOfPoint());
        Imgproc.convexHull(contour, hullIndices);

        for (int c = 0; c < hullIndices.rows(); c++) {
            int v = (int) hullIndices.get(c, 0)[0];
            hull.put(c, 0, contour.get(v, 0));
            // System.out.println(v);
        }

        // System.out.println(hull.size());

    }

    Imgproc.drawContours(cameraImage, hulls, -1, CONTOUR_COLOR);

    debugImage("Threshold Image", thresholdImage);
    // debugImage("Contour Image", contourImage);
}

From source file:org.usfirst.frc.team2084.CMonster2016.vision.BoulderProcessor.java

License:Open Source License

private static MatOfPoint convexHull(MatOfPoint contour) {
    MatOfInt hullMatrix = new MatOfInt();
    Imgproc.convexHull(contour, hullMatrix); // perform convex hull, gap
                                             // filler
    MatOfPoint hull = new MatOfPoint();
    hull.create(hullMatrix.rows(), 1, CvType.CV_32SC2);

    for (int r = 0; r < hullMatrix.rows(); r++) {
        hull.put(r, 0, contour.get((int) hullMatrix.get(r, 0)[0], 0));
    }/*  www. j  ava  2s . c  om*/

    return hull;
}

From source file:org.usfirst.frc.team2084.CMonster2016.vision.HighGoalProcessor.java

License:Open Source License

private MatOfPoint convexHull(MatOfPoint contour) {
    MatOfInt hullMatrix = new MatOfInt();
    Imgproc.convexHull(contour, hullMatrix); // perform convex hull, gap
                                             // filler
    MatOfPoint hull = new MatOfPoint();
    hull.create(hullMatrix.rows(), 1, CvType.CV_32SC2);

    for (int r = 0; r < hullMatrix.rows(); r++) {
        hull.put(r, 0, contour.get((int) hullMatrix.get(r, 0)[0], 0));
    }/*from w  ww .  j av  a2 s  . c  om*/

    return hull;
}

From source file:servlets.processScribble.java

/**
 * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
 * methods./*  w w w. j  ava2  s.c  om*/
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {

        String imageForTextRecognition = request.getParameter("imageForTextRecognition") + ".png";

        Mat original = ImageUtils.loadImage(imageForTextRecognition, request);
        Mat image = original.clone();
        Mat mask = Mat.zeros(image.rows() + 2, image.cols() + 2, CvType.CV_8UC1);

        String samplingPoints = request.getParameter("samplingPoints");

        Gson gson = new Gson();
        Point[] userPoints = gson.fromJson(samplingPoints, Point[].class);

        MatOfPoint points = new MatOfPoint(new Mat(userPoints.length, 1, CvType.CV_32SC2));
        int cont = 0;

        for (Point point : userPoints) {
            int y = (int) point.y;
            int x = (int) point.x;
            int[] data = { x, y };
            points.put(cont++, 0, data);
        }

        MatOfInt hull = new MatOfInt();
        Imgproc.convexHull(points, hull);

        MatOfPoint mopOut = new MatOfPoint();
        mopOut.create((int) hull.size().height, 1, CvType.CV_32SC2);

        int totalPoints = (int) hull.size().height;

        Point[] convexHullPoints = new Point[totalPoints];
        ArrayList<Point> seeds = new ArrayList<>();

        for (int i = 0; i < totalPoints; i++) {
            int index = (int) hull.get(i, 0)[0];
            double[] point = new double[] { points.get(index, 0)[0], points.get(index, 0)[1] };
            mopOut.put(i, 0, point);

            convexHullPoints[i] = new Point(point[0], point[1]);
            seeds.add(new Point(point[0], point[1]));

        }

        MatOfPoint mop = new MatOfPoint();
        mop.fromArray(convexHullPoints);

        ArrayList<MatOfPoint> arrayList = new ArrayList<MatOfPoint>();
        arrayList.add(mop);

        Random random = new Random();
        int b = random.nextInt(256);
        int g = random.nextInt(256);
        int r = random.nextInt(256);
        Scalar newVal = new Scalar(b, g, r);

        FloodFillFacade floodFillFacade = new FloodFillFacade();

        for (int i = 0; i < seeds.size(); i++) {
            Point seed = seeds.get(i);
            image = floodFillFacade.fill(image, mask, (int) seed.x, (int) seed.y, newVal);
        }

        Imgproc.drawContours(image, arrayList, 0, newVal, -1);

        Imgproc.resize(mask, mask, image.size());

        Scalar meanColor = Core.mean(original, mask);

        //            Highgui.imwrite("C:\\Users\\Gonzalo\\Documents\\NetBeansProjects\\iVoLVER\\uploads\\the_convexHull.png", image);
        ImageUtils.saveImage(image, imageForTextRecognition + "_the_convexHull.png", request);

        newVal = new Scalar(255, 255, 0);

        floodFillFacade.setMasked(false);
        System.out.println("Last one:");
        floodFillFacade.fill(image, mask, 211, 194, newVal);

        Core.circle(image, new Point(211, 194), 5, new Scalar(0, 0, 0), -1);
        ImageUtils.saveImage(image, imageForTextRecognition + "_final.png", request);
        //            Highgui.imwrite("C:\\Users\\Gonzalo\\Documents\\NetBeansProjects\\iVoLVER\\uploads\\final.png", image);

        Mat element = new Mat(3, 3, CvType.CV_8U, new Scalar(1));
        Imgproc.morphologyEx(mask, mask, Imgproc.MORPH_CLOSE, element, new Point(-1, -1), 3);

        Imgproc.resize(mask, mask, image.size());

        //            ImageUtils.saveImage(mask, "final_mask_dilated.png", request);
        //            Highgui.imwrite("C:\\Users\\Gonzalo\\Documents\\NetBeansProjects\\iVoLVER\\uploads\\final_mask_dilated.png", mask);

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Imgproc.findContours(mask.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL,
                Imgproc.CHAIN_APPROX_NONE);
        double contourArea = 0;
        String path = "";

        MatOfPoint biggestContour = contours.get(0); // getting the biggest contour
        contourArea = Imgproc.contourArea(biggestContour);

        if (contours.size() > 1) {
            biggestContour = Collections.max(contours, new ContourComparator()); // getting the biggest contour in case there are more than one
        }

        Point[] biggestContourPoints = biggestContour.toArray();
        path = "M " + (int) biggestContourPoints[0].x + " " + (int) biggestContourPoints[0].y + " ";
        for (int i = 1; i < biggestContourPoints.length; ++i) {
            Point v = biggestContourPoints[i];
            path += "L " + (int) v.x + " " + (int) v.y + " ";
        }
        path += "Z";

        System.out.println("path:");
        System.out.println(path);

        Rect computedSearchWindow = Imgproc.boundingRect(biggestContour);
        Point massCenter = computedSearchWindow.tl();

        FindingResponse findingResponse = new FindingResponse(path, meanColor, massCenter, -1, contourArea);
        String jsonResponse = gson.toJson(findingResponse, FindingResponse.class);

        out.println(jsonResponse);

        //            String jsonResponse = gson.toJson(path);
        //            out.println(jsonResponse);
    }
}

From source file:tv.danmaku.ijk.media.example.activities.VideoActivity.java

License:Apache License

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();/*from w  ww  .  j a v a  2  s  . com*/
    mGray = inputFrame.gray();

    //        return mRgba;
    //        iThreshold = 10000;

    //Imgproc.blur(mRgba, mRgba, new Size(5,5));
    Imgproc.GaussianBlur(mRgba, mRgba, new org.opencv.core.Size(3, 3), 1, 1);
    //Imgproc.medianBlur(mRgba, mRgba, 3);

    if (!mIsColorSelected)
        return mRgba;

    List<MatOfPoint> contours = mDetector.getContours();
    mDetector.process(mRgba);

    Log.d(TAG, "Contours count: " + contours.size());

    if (contours.size() <= 0) {
        return mRgba;
    }

    RotatedRect rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(0).toArray()));

    double boundWidth = rect.size.width;
    double boundHeight = rect.size.height;
    int boundPos = 0;

    for (int i = 1; i < contours.size(); i++) {
        rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
        if (rect.size.width * rect.size.height > boundWidth * boundHeight) {
            boundWidth = rect.size.width;
            boundHeight = rect.size.height;
            boundPos = i;
        }
    }

    Rect boundRect = Imgproc.boundingRect(new MatOfPoint(contours.get(boundPos).toArray()));
    Imgproc.rectangle(mRgba, boundRect.tl(), boundRect.br(), CONTOUR_COLOR_WHITE, 2, 8, 0);

    Log.d(TAG, " Row start [" + (int) boundRect.tl().y + "] row end [" + (int) boundRect.br().y
            + "] Col start [" + (int) boundRect.tl().x + "] Col end [" + (int) boundRect.br().x + "]");

    int rectHeightThresh = 0;
    double a = boundRect.br().y - boundRect.tl().y;
    a = a * 0.7;
    a = boundRect.tl().y + a;

    Log.d(TAG, " A [" + a + "] br y - tl y = [" + (boundRect.br().y - boundRect.tl().y) + "]");

    //Core.rectangle( mRgba, boundRect.tl(), boundRect.br(), CONTOUR_COLOR, 2, 8, 0 );
    Imgproc.rectangle(mRgba, boundRect.tl(), new Point(boundRect.br().x, a), CONTOUR_COLOR, 2, 8, 0);

    MatOfPoint2f pointMat = new MatOfPoint2f();
    Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(boundPos).toArray()), pointMat, 3, true);
    contours.set(boundPos, new MatOfPoint(pointMat.toArray()));

    MatOfInt hull = new MatOfInt();
    MatOfInt4 convexDefect = new MatOfInt4();
    Imgproc.convexHull(new MatOfPoint(contours.get(boundPos).toArray()), hull);

    if (hull.toArray().length < 3)
        return mRgba;

    Imgproc.convexityDefects(new MatOfPoint(contours.get(boundPos).toArray()), hull, convexDefect);

    List<MatOfPoint> hullPoints = new LinkedList<MatOfPoint>();
    List<Point> listPo = new LinkedList<Point>();
    for (int j = 0; j < hull.toList().size(); j++) {
        listPo.add(contours.get(boundPos).toList().get(hull.toList().get(j)));
    }

    MatOfPoint e = new MatOfPoint();
    e.fromList(listPo);
    hullPoints.add(e);

    List<MatOfPoint> defectPoints = new LinkedList<MatOfPoint>();
    List<Point> listPoDefect = new LinkedList<Point>();
    for (int j = 0; j < convexDefect.toList().size(); j = j + 4) {
        Point farPoint = contours.get(boundPos).toList().get(convexDefect.toList().get(j + 2));
        Integer depth = convexDefect.toList().get(j + 3);
        if (depth > iThreshold && farPoint.y < a) {
            listPoDefect.add(contours.get(boundPos).toList().get(convexDefect.toList().get(j + 2)));
        }
        Log.d(TAG, "defects [" + j + "] " + convexDefect.toList().get(j + 3));
    }

    MatOfPoint e2 = new MatOfPoint();
    e2.fromList(listPo);
    defectPoints.add(e2);

    Log.d(TAG, "hull: " + hull.toList());
    Log.d(TAG, "defects: " + convexDefect.toList());

    Imgproc.drawContours(mRgba, hullPoints, -1, CONTOUR_COLOR, 3);

    int defectsTotal = (int) convexDefect.total();
    Log.d(TAG, "Defect total " + defectsTotal);

    this.numberOfFingers = listPoDefect.size();
    if (this.numberOfFingers > 5)
        this.numberOfFingers = 5;

    mHandler.post(mUpdateFingerCountResults);

    for (Point p : listPoDefect) {
        Imgproc.circle(mRgba, p, 6, new Scalar(255, 0, 255));
    }

    return mRgba;
}