Ejemplo n.º 1
0
 /** Remove this child node, and make sure our parent absorbs our pixel statistics. */
 void pruneChild() {
   --parent.nchild;
   parent.unique += unique;
   parent.total_red += total_red;
   parent.total_green += total_green;
   parent.total_blue += total_blue;
   parent.child[id] = null;
   --cube.nodes;
   cube = null;
   parent = null;
 }
Ejemplo n.º 2
0
    /*
     * Procedure Classification begins by initializing a color
     * description tree of sufficient depth to represent each
     * possible input color in a leaf. However, it is impractical
     * to generate a fully-formed color description tree in the
     * classification phase for realistic values of cmax. If
     * colors components in the input image are quantized to k-bit
     * precision, so that cmax= 2k-1, the tree would need k levels
     * below the root node to allow representing each possible
     * input color in a leaf. This becomes prohibitive because the
     * tree's total number of nodes is 1 + sum(i=1,k,8k).
     *
     * A complete tree would require 19,173,961 nodes for k = 8,
     * cmax = 255. Therefore, to avoid building a fully populated
     * tree, QUANTIZE: (1) Initializes data structures for nodes
     * only as they are needed; (2) Chooses a maximum depth for
     * the tree as a function of the desired number of colors in
     * the output image (currently log2(colormap size)).
     *
     * For each pixel in the input image, classification scans
     * downward from the root of the color description tree. At
     * each level of the tree it identifies the single node which
     * represents a cube in RGB space containing It updates the
     * following data for each such node:
     *
     *   number_pixels : Number of pixels whose color is contained
     *   in the RGB cube which this node represents;
     *
     *   unique : Number of pixels whose color is not represented
     *   in a node at lower depth in the tree; initially, n2 = 0
     *   for all nodes except leaves of the tree.
     *
     *   total_red/green/blue : Sums of the red, green, and blue
     *   component values for all pixels not classified at a lower
     *   depth. The combination of these sums and n2 will
     *   ultimately characterize the mean color of a set of pixels
     *   represented by this node.
     */
    void classification() {
      int pixels[][] = this.pixels;

      int width = pixels.length;
      int height = pixels[0].length;

      // convert to indexed color
      for (int x = width; x-- > 0; ) {
        for (int y = height; y-- > 0; ) {
          int pixel = pixels[x][y];
          int alpha = (pixel >> 24) & 0xFF;
          if (alpha != 255) {
            hasTrans = true;
            continue; // don't add transparent pixels to the cube
          }
          int red = (pixel >> 16) & 0xFF;
          int green = (pixel >> 8) & 0xFF;
          int blue = (pixel >> 0) & 0xFF;

          // a hard limit on the number of nodes in the tree
          if (nodes > MAX_NODES) {
            System.out.println("pruning");
            root.pruneLevel();
            --depth;
          }

          // walk the tree to depth, increasing the
          // number_pixels count for each node
          Node node = root;
          for (int level = 1; level <= depth; ++level) {
            int id =
                (((red > node.mid_red ? 1 : 0) << 0)
                    | ((green > node.mid_green ? 1 : 0) << 1)
                    | ((blue > node.mid_blue ? 1 : 0) << 2));
            if (node.child[id] == null) {
              new Node(node, id, level);
            }
            node = node.child[id];
            node.number_pixels += SHIFT[level];
          }

          ++node.unique;
          node.total_red += red;
          node.total_green += green;
          node.total_blue += blue;
        }
      }

      // if we have transparent pixels, that cuts into the number
      // of other colors we can use.
      if (hasTrans) {
        this.max_colors--;
      }
    }