Ask Your Question
0

kmeans in Android (Java)-

asked Aug 16 '19

LiorA gravatar image

updated Aug 16 '19

Hi,

I've tried to use kmeans function, but something is not clear to me.

Lets say that I have an array of points and I want to center all of them to four points :

topLeft, topRight, bottomeft, bottomRight.

How I can achieve it ? I tried to make it work, but failed to understand (for now)..

also, It's very hard to understand what is happening on the Mat's.. No option to print/see the actual Mat on some console / or in deug mode ?

Thank's !!

the code:

public void colorMask(View view)
{
    //Image Input :
    Bitmap one =
            drawableToBitmap(getResources().getDrawable(R.drawable.dsc_1304_cutted_bigger, this.getTheme()));
    Mat img1 = new Mat();
    Utils.bitmapToMat(one, img1, true);// moving one to img1 Mat structure.


    // downsize the image.
    Mat pyrDowntmp = new Mat();
    Imgproc.resize(img1, pyrDowntmp, new Size(img1.cols() / 4, img1.rows() / 4));
    img1.release();

    Mat pyrDown = new Mat();
    cvtColor(pyrDowntmp, pyrDown, COLOR_RGBA2RGB);
    pyrDowntmp.release();


    List<Point> intersections1 = new ArrayList<>();


    org.opencv.core.Point pointsArray[] = new org.opencv.core.Point[ intersections1.size() ];
    intersections1.toArray(pointsArray);


    Mat intersections = new Mat();
    Mat intersections32f = new Mat();


    // draw all the intersections. (see it ok)
    for (Point point: pointsArray)
    {
        // draw on the actual image:
        circle(pyrDown, point, 5, new Scalar(255, 0, 0), 2);//Red

        // want to draw it on a Mat that will be given to kmeans as data mat.

        // tried to draw on a mat:
        circle(intersections, point, 5, new Scalar(255, 0, 0), 2);

        // tried to 'put' on 32f Mat.
        //(the first two parameters - issue an error.('need double')
        intersections32f.put(point.x, point.y, 1.0);
    }



    intersections.convertTo(intersections32f, CvType.CV_32F);

    // want to find the 4 corners of the points..
    Mat labels = Mat.zeros(intersections32f.rows(), intersections32f.cols(), CvType.CV_32F);

    labels.put(0, 0, 1.0); // topLeft

    labels.put(0, labels.rows() - 1, 1); // bottomLeft

    labels.put(labels.cols() - 1, 0, 1); // topRight

    labels.put(labels.rows() - 1, labels.cols() - 1, 1); // bottomRight


    TermCriteria criteria = new TermCriteria(TermCriteria.COUNT, 100, 1);
    int attempts = 50;
    int flags = Core.KMEANS_PP_CENTERS;
    Mat centers = new Mat();
    double res = kmeans(intersections32f, 4, labels, criteria, attempts, flags, centers);


    Bitmap imageMatched = Bitmap.createBitmap(centers.cols(), centers.rows(), Bitmap.Config.RGB_565);
    Utils.matToBitmap(centers, imageMatched);
    imageViewMy.setImageBitmap(imageMatched);

    /*
    public static double kmeans(@NotNull Mat data,
    int K,
    @NotNull Mat bestLabels,
    @NotNull TermCriteria criteria,
    int attempts,
    int flags)
    */


}
Preview: (hide)

Comments

i don't think it's possible to preselect centers here, only labels (meaning, one per pixel)

berak gravatar imageberak (Aug 16 '19)edit

Kmeans is a clustering algorithm. This means it will try to for groups of datapoints related to each other. Its does this by measuring a distance.

How it works(very simplified):
Initial:
Define n clusters and give them a random position 

Repeat for each cluster until a cluster is empty or all points have been assigned
1) Check which points are closest to the center of the cluster
2) Assign the points from 1) to the cluster
3) Computer the average over all points and that the new center

So i dont think this algorithm will solve your problem "I want to center all of them to four points" because the cluster center will be moved constantly and maybe ends up in a position which is out of your bounding box.

You could try running with 1 cluster and a min distance anways.
holger gravatar imageholger (Aug 16 '19)edit

@berak , yes, you are correct, but I'm not fully understood the label's role in the algorithm.

data/samples - the points in the grid.

K - the number of wanted clusters.

label - ...

Criteria - the base condition.

attempts - the number of times which the algorithm is executed using different initial labellings.

flags - behavioral flags.

centers - output of K points.

what is the labels ? Is it for 'color' different points ?.

LiorA gravatar imageLiorA (Aug 16 '19)edit

@holger

If I define K=4 , and most points are in clusters - the center of each cluster is what I want..

I need something like this : https://docs.opencv.org/3.0-beta/doc/...

If I have the following : https://imgur.com/a/EHECQqS

And I want to get the center of each cluster, kmeans is not for it ?

LiorA gravatar imageLiorA (Aug 16 '19)edit

No - each cluster has a center - the so called centroid. Which is just the average of all points. The role of the labels - i am at home so i cannot look it up - i think the labels just tells you to which cluster a point belongs to.

holger gravatar imageholger (Aug 17 '19)edit

1 answer

Sort by » oldest newest most voted
0

answered Aug 31 '19

LiorA gravatar image

So this is exactly what I looking for...

Preview: (hide)

Question Tools

1 follower

Stats

Asked: Aug 16 '19

Seen: 1,494 times

Last updated: Aug 16 '19