在OpenCV Android中查找相机框架中的主色

nuw*_*ara 4 c++ android opencv image-processing android-camera

我想在Android CvCameraViewFrame对象中获得主色.我使用以下OpenCV Android代码来做到这一点.此代码从OpenCV c ++代码转换为OpenCV Android代码.在下面的代码中,我遍历相机框架中的所有像素,找到每个像素的颜色并将它们存储在HashMap中,以便在循环结束时找到主色.要遍历每个像素,大约需要30秒.这对我来说是不可接受的.有人可以回顾一下这段代码并指出我如何找到相机框架中的主色.

private String[] colors = {"cBLACK", "cWHITE", "cGREY", "cRED", "cORANGE", "cYELLOW", "cGREEN", "cAQUA", "cBLUE", "cPURPLE", "cPINK", "cRED"};

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();

        if (mIsColorSelected) {
            Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_BGR2HSV);

            int h = mRgba.height();             // Pixel height
            int w = mRgba.width();              // Pixel width
            int rowSize = (int)mRgba.step1();       // Size of row in bytes, including extra padding

            float initialConfidence = 1.0f;

            Map<String, Integer> tallyColors = new HashMap<String, Integer>();

            byte[] pixelsTotal = new byte[h*rowSize];
            mRgba.get(0,0,pixelsTotal);

            //This for loop takes about 30 seconds to process for my camera frame
            for (int y=0; y<h; y++) {
                for (int x=0; x<w; x++) {
                    // Get the HSV pixel components

                    int hVal = (int)pixelsTotal[(y*rowSize) + x + 0];   // Hue
                    int sVal = (int)pixelsTotal[(y*rowSize) + x + 1];   // Saturation
                    int vVal = (int)pixelsTotal[(y*rowSize) + x + 2];   // Value (Brightness)


                    // Determine what type of color the HSV pixel is.
                    String ctype = getPixelColorType(hVal, sVal, vVal);
                    // Keep count of these colors.
                    int totalNum = 0;
                    try{
                        totalNum = tallyColors.get(ctype);
                    } catch(Exception ex){
                        totalNum = 0;
                    }
                    totalNum++;
                    tallyColors.put(ctype, totalNum);
                }
            }

            int tallyMaxIndex = 0;
            int tallyMaxCount = -1;
            int pixels = w * h;
            for (int i=0; i<colors.length; i++) {
                String v = colors[i];
                int pixCount;
                try{
                    pixCount = tallyColors.get(v);
                } catch(Exception e){
                    pixCount = 0;
                }
                Log.i(TAG, v + " - " + (pixCount*100/pixels) + "%, ");
                if (pixCount > tallyMaxCount) {
                    tallyMaxCount = pixCount;
                    tallyMaxIndex = i;
                }
            }
            float percentage = initialConfidence * (tallyMaxCount * 100 / pixels);
            Log.i(TAG, "Color of currency note: " + colors[tallyMaxIndex] + " (" + percentage + "% confidence).");

        }

        return mRgba;
    }

    private String getPixelColorType(int H, int S, int V)
    {
        String color;
        if (V < 75)
            color = "cBLACK";
        else if (V > 190 && S < 27)
            color = "cWHITE";
        else if (S < 53 && V < 185)
            color = "cGREY";
        else {  // Is a color
            if (H < 14)
                color = "cRED";
            else if (H < 25)
                color = "cORANGE";
            else if (H < 34)
                color = "cYELLOW";
            else if (H < 73)
                color = "cGREEN";
            else if (H < 102)
                color = "cAQUA";
            else if (H < 127)
                color = "cBLUE";
            else if (H < 149)
                color = "cPURPLE";
            else if (H < 175)
                color = "cPINK";
            else    // full circle 
                color = "cRED"; // back to Red
        }
        return color;
    }
Run Code Online (Sandbox Code Playgroud)

非常感谢你.

Rui*_*ues 5

OpenCV有一个直方图方法,可以计算所有图像颜色.在计算直方图后,您所要做的就是选择计数最大的那个...

在这里查看教程(C++):直方图计算.

您也可以使用此stackoverflow答案,其中显示了如何使用Android的直方图函数的示例Imgproc.calcHist().