代码之家  ›  专栏  ›  技术社区  ›  ProgrammingCuber

按矩形坐标对颜色排序

  •  0
  • ProgrammingCuber  · 技术社区  · 7 年前

    我正在开发一个程序,在这个程序中,我拍摄了一张照片,找到照片中的正方形,然后确定它们的RGB值。我能够成功地获得这些信息,但当我找到RGB值和坐标时,它们按照我找到的轮廓的顺序排列。我的问题是,我怎样才能把颜色分类,让我像看书一样从左上角一行读到底行。每种颜色都有矩形坐标,我想用它来帮我排序。

    我有一张图片,上面显示了我想要点的东西。

    image I want to order

    当我从图像中获得RGB值时,我打印出颜色和坐标。下面是它的样子(注意它们是如何被订购的):

    279,271
    R: 106 G: 255 B: 183 
    
    188,270
    R: 107 G: 255 B: 180 
    
    371,267
    R: 102 G: 255 B: 169 
    
    274,178
    R: 75 G: 255 B: 99 
    
    185,179
    R: 84 G: 255 B: 103 
    
    369,175
    R: 89 G: 255 B: 105 
    
    277,88
    R: 96 G: 255 B: 103 
    
    184,85
    R: 101 G: 255 B: 110 
    
    370,84
    R: 124 G: 255 B: 126 
    

    我用来获取它们的代码如下:

    我只是不知道怎样才能把颜色分类存储。

    private void getColors(Mat img2read , Rect roi){
        int rAvg = 0 , bAvg = 0, gAvg = 0;
        int rSum = 0, bSum = 0, gSum = 0;
    
        img2read = new Mat(img2read, roi); //image size of rect (saved contour size and coordinates)
        img2read.convertTo(img2read, CvType.CV_8UC1); //convert to workable type for getting RGB data
    
        int totalBytes = (int) (img2read.total() * img2read.channels());
        byte buff[] = new byte[totalBytes];
        int channels = img2read.channels();
    
        img2read.get(0,0,buff);
        int stride = channels * img2read.width();
        for(int i = 0; i < img2read.height();i++){
            for(int x = 0; x < stride; x+= channels){
                int r = unsignedToBytes(buff[(i * stride) + x]);
                int g = unsignedToBytes(buff[(i * stride)+ x + 1]);
                int b = unsignedToBytes(buff[(i * stride)+ x + 2]);
    
                rSum += r;
                gSum += g;
                bSum += b;
    
            }
        }
        float[] hsv = new float[3];
    
        rAvg = (int) (rSum / img2read.total());
        gAvg = (int) (gSum /  img2read.total());
        bAvg = (int) (bSum / img2read.total());
    
    
        Color.RGBtoHSB(rAvg, gAvg, bAvg, hsv);
    
        hsv[2] = 1; //Set to max value
    
        int rgb = Color.HSBtoRGB(hsv[0], hsv[1], hsv[2]);
    
        Color brightenedColor = new Color(rgb);
        System.out.println();
        System.out.println(roi.x + "," + roi.y);
        System.out.printf("R: %s G: %s B: %s \n", brightenedColor.getRed(), brightenedColor.getGreen(), brightenedColor.getBlue());     
        Color colorToAdd = new Color(brightenedColor.getRed(), brightenedColor.getGreen(), brightenedColor.getBlue());
        Point coords = new Point(roi.x, roi.y);
        //colorCoords.put(coords, colorToAdd);
        /*counter++;
        if(counter == 9){
            sortColors(colorCoords);
        }*/
    }
    
    int counter = 0;
    
    Map <Point, Color> colorCoords = new TreeMap<>();
    Color[] colorArray = new Color[54];
    int currentIndex = 0;
    
    //Not really sure what I'm doing here but I don't think it is right.
    private void sortColors(Map<Point, Color> colorCoords){
    
        for(int i = 0; i < colorCoords.size();i++){
        //  colorCoords.get(key)
        }
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Usagi Miyamoto    7 年前

    将这些值放入对象中,并将其存储到 List . 要排序,可以添加静态 Comparator 字段,或使其实现 Comparable 类似这样:

    public class Block implement Comparable<Block> {
       public int x, y;
       public Color color;
       @Override
       public int compareTo(Block other) {
          if (null==other) throw new NullPointerException();
          // implement the logic, like:
          // this will compare X, unless difference in Y is more than EG 10
          return Math.abs(y - other.y) > 10 ? y - other.y : x - other.x;
       }
       public Color getColor() { return color; }
    }
    
    public List<Block> blocks = new ArrayList<>();
    

    要排序,可以使用

    Collections.sort(blocks);
    

    编辑了上述比较,以满足您的需要。。。


    Java8 得到一个排序的数组应该是可行的 Color

     Color[] colors = blocks.stream().sorted().map(Block::getColor).toArray();
    

    为了让它发挥作用 Block.getColor()

        2
  •  0
  •   Jason Trader    7 年前