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

时间:2014-02-20 15:18:21

标签: android c++ 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;
    }

非常感谢。

3 个答案:

答案 0 :(得分:5)

OpenCV有Histogram method计算所有图像颜色。在计算直方图之后,您所要做的就是选择计数最大的那个......

点击此处查看教程(C ++):Histogram Calculation.

您可能还会this stackoverflow answer显示有关如何使用Android的直方图函数Imgproc.calcHist()的示例。

答案 1 :(得分:4)

考虑调整图像大小,然后将结果乘以相同的比例:

resize( larg_image, smallerImage , interpolation=cv.CV_INTER_CUBIC );

或者, 你可以查看these solutions:

答案 2 :(得分:0)

您可以使用k-mean聚类方法找到主色。 这个链接很有用。 https://www.youtube.com/watch?v=f54-x3PckH8