androidopencvcolorsimage-recognition

What is the best way to implement Color Detection in Android?


I want to implement color detection in Android. What I exactly want to do is that after taking a picture with Android Camera, I want to detect the color of object in that picture. My goal is detecting colors according to color intensity. At this point, I searched and saw different approaches related to this goal. There are some algorithms which converts the images into Bitmap and then detects the colors, some of them use RGB. Additionally, I saw that OpenCV is also a known solution for this problem.

Now, I wonder which way I should follow. Which way is better for my case. Are there anyone who can help and direct me through a method?

Any help will be appreciated. Thank you all in advance.


Solution

  • If I understand your question correctly, you want a method that will take an image and determine the most dominant color in that method and then return the result.

    I have put together a class that should provide you with the result, don't know if it's the most efficient algorithm but give it a try. To implement the solution you can do the following

    new ColorFinder(new CallbackInterface() {
        @Override
        public void onCompleted(String color) {
            Toast.makeText(context, "Your Color : " + color, Toast.LENGTH_SHORT).show();
        }
    }).findDominantColor(yourBitmap);
    

    ColorFinder.java

    import android.graphics.Bitmap;
    import android.os.AsyncTask;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Created by Neil on 15/02/23.
     */
    public class ColorFinder {
        private static final String TAG = ColorFinder.class.getSimpleName();
    
        private CallbackInterface callback;
    
        public ColorFinder(CallbackInterface callback) {
            this.callback = callback;
        }
    
        public void findDominantColor(Bitmap bitmap) {
            new GetDominantColor().execute(bitmap);
        }
    
        private int getDominantColorFromBitmap(Bitmap bitmap) {
            int [] pixels = new int[bitmap.getWidth()*bitmap.getHeight()];
            bitmap.getPixels(pixels,0,bitmap.getWidth(),0,0, bitmap.getWidth(), bitmap.getHeight());
    
            Map<Integer, PixelObject> pixelList = getMostDominantPixelList(pixels);
            return getDominantPixel(pixelList);
        }
    
        private Map<Integer, PixelObject> getMostDominantPixelList(int [] pixels) {
            Map<Integer, PixelObject> pixelList = new HashMap<>();
    
            for (int pixel : pixels) {
                if (pixelList.containsKey(pixel)) {
                    pixelList.get(pixel).pixelCount++;
                } else {
                    pixelList.put(pixel, new PixelObject(pixel, 1));
                }
            }
    
            return pixelList;
        }
    
        private int getDominantPixel(Map<Integer, PixelObject> pixelList) {
            int dominantColor = 0;
            int largestCount = 0;
            for (Map.Entry<Integer, PixelObject> entry : pixelList.entrySet()) {
                PixelObject pixelObject = entry.getValue();
    
                if (pixelObject.pixelCount > largestCount) {
                    largestCount = pixelObject.pixelCount;
                    dominantColor = pixelObject.pixel;
                }
            }
    
            return dominantColor;
        }
    
        private class GetDominantColor extends AsyncTask<Bitmap, Integer, Integer> {
    
            @Override
            protected Integer doInBackground(Bitmap... params) {
                int dominantColor = getDominantColorFromBitmap(params[0]);
                return dominantColor;
            }
    
            @Override
            protected void onPostExecute(Integer dominantColor) {
                String hexColor = colorToHex(dominantColor);
                if (callback != null)
                    callback.onCompleted(hexColor);
            }
    
            private String colorToHex(int color) {
                return String.format("#%06X", (0xFFFFFF & color));
            }
        }
    
        public interface CallbackInterface {
            public void onCompleted(String dominantColor);
        }
    }
    

    PixelObject.java

    public class PixelObject {
        public int pixel;
        public int pixelCount;
    
        public PixelObject(int pixel, int pixelCount) {
            this.pixel = pixel;
            this.pixelCount = pixelCount;
        }
    }