⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 colorlayout.java

📁 图像检索的代码b
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * This file is part of Caliph & Emir.
 *
 * Caliph & Emir is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Caliph & Emir is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Caliph & Emir; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Copyright statement:
 * --------------------
 * (c) 2002-2004 by Mathias Lux (mathias@juggle.at)
 * http://www.juggle.at
 */

/*
 *
 *
 *
 * @author Mathias Lux, mathias@juggle.at
 * Date: 16.09.2002
 * Time: 14:45:06
 */
package at.lux.imageanalysis;

import org.jdom.Element;
import org.jdom.Namespace;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;


/**
 * Class for extrcating & comparing MPEG-7 based CBIR descriptor ColorLayout
 * @author Mathias Lux, mathias@juggle.at
 */
public class ColorLayout {
    // static final boolean debug = true;
    private int[][] shape;
    private int imgYSize, imgXSize;
    private BufferedImage img;

    private static int[] availableCoeffNumbers = {1, 3, 6, 10, 15, 21, 28, 64};

    private int[] YCoeff, CbCoeff, CrCoeff;

    private int numCCoeff = 3, numYCoeff = 6;

    private static int[] arrayZigZag = {
        0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
        12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
        35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
        58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
    };

    private static double[][] arrayCosin = {
        {
            3.535534e-01, 3.535534e-01, 3.535534e-01, 3.535534e-01,
            3.535534e-01, 3.535534e-01, 3.535534e-01, 3.535534e-01
        },
        {
            4.903926e-01, 4.157348e-01, 2.777851e-01, 9.754516e-02,
            -9.754516e-02, -2.777851e-01, -4.157348e-01, -4.903926e-01
        },
        {
            4.619398e-01, 1.913417e-01, -1.913417e-01, -4.619398e-01,
            -4.619398e-01, -1.913417e-01, 1.913417e-01, 4.619398e-01
        },
        {
            4.157348e-01, -9.754516e-02, -4.903926e-01, -2.777851e-01,
            2.777851e-01, 4.903926e-01, 9.754516e-02, -4.157348e-01
        },
        {
            3.535534e-01, -3.535534e-01, -3.535534e-01, 3.535534e-01,
            3.535534e-01, -3.535534e-01, -3.535534e-01, 3.535534e-01
        },
        {
            2.777851e-01, -4.903926e-01, 9.754516e-02, 4.157348e-01,
            -4.157348e-01, -9.754516e-02, 4.903926e-01, -2.777851e-01
        },
        {
            1.913417e-01, -4.619398e-01, 4.619398e-01, -1.913417e-01,
            -1.913417e-01, 4.619398e-01, -4.619398e-01, 1.913417e-01
        },
        {
            9.754516e-02, -2.777851e-01, 4.157348e-01, -4.903926e-01,
            4.903926e-01, -4.157348e-01, 2.777851e-01, -9.754516e-02
        }
    };
    private static int[][] weightMatrix = new int[3][64];
    private BufferedImage colorLayoutImage;

    /**
     * Create a ColorLayout Object from the given BufferedImage. 6 Y and 3 C Coefficients are used,
     * if you want to use another number you have to set it with the Setters.
     * @param image the input image
     */
    public ColorLayout(BufferedImage image) {
        this.img = image;
        imgYSize = image.getHeight();
        imgXSize = image.getWidth();
        init();
    }

    /**
     * Create a ColorLayout Object from the given BufferedImage with the desired number of Coefficients
     * @param image the input image
     * @param numberOfYCoeff desired number of Y Coefficients
     * @param numberOfCCoeff desired number of Cr and Cb Coefficients
     */
    public ColorLayout(int numberOfYCoeff, int numberOfCCoeff, BufferedImage image) {
        this.numCCoeff = getRightCoeffNumber(numberOfCCoeff);
        this.numYCoeff = getRightCoeffNumber(numberOfYCoeff);
        this.img = image;
        imgYSize = image.getHeight();
        imgXSize = image.getWidth();
        init();
    }

    /**
     * Create a ColorLayout Object from its descriptor
     * @param descriptor the descriptor as JDOM Element
     */
    public ColorLayout(Element descriptor) {
        this.img = null;
        YCoeff = new int[64];
        CbCoeff = new int[64];
        CrCoeff = new int[64];
        colorLayoutImage = null;

        Vector v = getCoeffs(descriptor);
        if (v != null) {
            int[] y = (int[]) v.get(0);
            int[] cb = (int[]) v.get(1);
            int[] cr = (int[]) v.get(2);
            for (int i = 0; i < 64; i++) {
                if (i < y.length) {
                    YCoeff[i] = y[i];
                } else {
                    YCoeff[i] = 16;
                }
                if (i < cb.length) {
                    CbCoeff[i] = cb[i];
                    CrCoeff[i] = cr[i];
                } else {
                    CbCoeff[i] = 16;
                    CrCoeff[i] = 16;
                }

            }
        } else {
//            debug("Descriptor not valid!!!");
        }
    }

    /**
     * init used by all constructors
     */
    private void init() {
        shape = new int[3][64];
        YCoeff = new int[64];
        CbCoeff = new int[64];
        CrCoeff = new int[64];
        colorLayoutImage = null;
        extract();
    }

    private void createShape() {
        int y_axis, x_axis;
        int i, k, x, y, j;
        long[][] sum = new long[3][64];
        int[] cnt = new int[64];
        double yy = 0.0;
        int R,G,B;

        //init of the blocks
        for (i = 0; i < 64; i++) {
            cnt[i] = 0;
            sum[0][i] = 0;
            sum[1][i] = 0;
            sum[2][i] = 0;
            shape[0][i] = 0;
            shape[1][i] = 0;
            shape[2][i] = 0;
        }

        WritableRaster raster = img.getRaster();
        int[] pixel = {0, 0, 0};
        for (y = 0; y < imgYSize; y++) {
            for (x = 0; x < imgXSize; x++) {
                raster.getPixel(x, y, pixel);
                R = pixel[0];
                G = pixel[1];
                B = pixel[2];

                y_axis = (int) (y / (imgYSize / 8.0));
                x_axis = (int) (x / (imgXSize / 8.0));

                k = y_axis * 8 + x_axis;

                //RGB to YCbCr, partition and average-calculation
                yy = (0.299 * R + 0.587 * G + 0.114 * B) / 256.0;
                sum[0][k] += (int) (219.0 * yy + 16.5); // Y
                sum[1][k] += (int) (224.0 * 0.564 * (B / 256.0 * 1.0 - yy) + 128.5); // Cb
                sum[2][k] += (int) (224.0 * 0.713 * (R / 256.0 * 1.0 - yy) + 128.5); // Cr
                cnt[k]++;
            }
        }

        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                for (k = 0; k < 3; k++) {
                    if (cnt[i * 8 + j] != 0)
                        shape[k][i * 8 + j] = (int) (sum[k][i * 8 + j] / cnt[i * 8 + j]);
                    else
                        shape[k][i * 8 + j] = 0;
                }
            }
        }
    }

    private void Fdct(int[] shapes) {
        int i, j ,k;
        double s;
        double[] dct = new double[64];

        //calculation of the cos-values of the second sum
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                s = 0.0;
                for (k = 0; k < 8; k++)
                    s += arrayCosin[j][k] * shapes[8 * i + k];
                dct[8 * i + j] = s;
            }
        }

        for (j = 0; j < 8; j++) {
            for (i = 0; i < 8; i++) {
                s = 0.0;
                for (k = 0; k < 8; k++)
                    s += arrayCosin[i][k] * dct[8 * k + j];
                shapes[8 * i + j] = (int) Math.floor(s + 0.499999);
            }
        }
    }

    private int quant_ydc(int i) {
        int j;
        if (i > 192)
            j = 112 + (i - 192) / 4;
        else if (i > 160)
            j = 96 + (i - 160) / 2;
        else if (i > 96)
            j = 32 + (i - 96);
        else if (i > 64)
            j = 16 + (i - 64) / 2;
        else
            j = i / 4;

        return j;
    }

    private int quant_cdc(int i) {
        int j;
        if (i > 191)
            j = 63;
        else if (i > 160)
            j = 56 + (i - 160) / 4;
        else if (i > 144)
            j = 48 + (i - 144) / 2;
        else if (i > 112)
            j = 16 + (i - 112);
        else if (i > 96)
            j = 8 + (i - 96) / 2;
        else if (i > 64)
            j = (i - 64) / 4;
        else
            j = 0;

        return j;
    }


    private int quant_ac(int i) {
        int j;

        if (i > 255)
            i = 255;
        //if(i > 239)
        //i = 239;
        if (i < -256)
            i = -256;
        if ((Math.abs(i)) > 127)
            j = 64 + (Math.abs(i)) / 4;
        else if ((Math.abs(i)) > 63)
            j = 32 + (Math.abs(i)) / 2;
        else
            j = Math.abs(i);
        j = (i < 0) ? -j :j;

        j += 128;
        //j+=132;

        return j;
    }

    private int extract() {

        createShape();

        Fdct(shape[0]);
        Fdct(shape[1]);
        Fdct(shape[2]);

        YCoeff[0] = quant_ydc(shape[0][0] >> 3) >> 1;
        CbCoeff[0] = quant_cdc(shape[1][0] >> 3);
        CrCoeff[0] = quant_cdc(shape[2][0] >> 3);

        //quantization and zig-zagging
        for (int i = 1; i < 64; i++) {
            YCoeff[i] = quant_ac((shape[0][(arrayZigZag[i])]) >> 1) >> 3;
            CbCoeff[i] = quant_ac(shape[1][(arrayZigZag[i])]) >> 3;
            CrCoeff[i] = quant_ac(shape[2][(arrayZigZag[i])]) >> 3;
        }

        setYCoeff(YCoeff);
        setCbCoeff(CbCoeff);
        setCrCoeff(CrCoeff);
        return 0;
    }

    public Element getDescriptor() {
        Namespace mpeg7, xsi;
        mpeg7 = Namespace.getNamespace("", "urn:mpeg:mpeg7:schema:2001");
        xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

        Element vdesc = new Element("VisualDescriptor", mpeg7).setAttribute("type", "ColorLayoutType", xsi);
        // Ersten Werte:
        Element ydc, cbdc, crdc;
        ydc = new Element("YDCCoeff", mpeg7).addContent(YCoeff[0] + "");
        cbdc = new Element("CbDCCoeff", mpeg7).addContent(CbCoeff[0] + "");
        crdc = new Element("CrDCCoeff", mpeg7).addContent(CrCoeff[0] + "");
        vdesc.addContent(ydc);
        vdesc.addContent(cbdc);
        vdesc.addContent(crdc);
        if (numYCoeff > 1) {
            Element yac = new Element("YACCoeff" + (numYCoeff - 1), mpeg7);
            StringBuffer b = new StringBuffer();
            for (int i = 1; i < numYCoeff; i++) {
                b.append(YCoeff[i] + " ");
            }
            yac.setText(b.toString().trim());
            vdesc.addContent(yac);
        }
        if (numCCoeff > 1) {
            Element cbac = new Element("CbACCoeff" + (numCCoeff - 1), mpeg7);
            Element crac = new Element("CrACCoeff" + (numCCoeff - 1), mpeg7);
            StringBuffer bcb, bcr;
            bcb = new StringBuffer();
            bcr = new StringBuffer();
            for (int i = 1; i < numCCoeff; i++) {
                bcb.append(CbCoeff[i] + " ");
                bcr.append(CrCoeff[i] + " ");
            }
            cbac.setText(bcb.toString().trim());
            crac.setText(bcr.toString().trim());

            vdesc.addContent(cbac);
            vdesc.addContent(crac);
        }

        return vdesc;
    }

    private void setYCoeff(int[] YCoeff) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -