Histogram je speciální typ grafu, který vyjadřuje hodnotu jasu v obrázku, černou zpravidla vyjadřujeme vlevo a bílou vpravo. Hodnoty sloupců vyjadřují počet pixelů dané hodnoty jasu v grafu. Zjednodušeně řečeno se jedná o graf rozložení „jasů“ v obrázku.
1. Načteme si obrázek a uložíme jej s datovým typem BufferedImage.
2. Deklarujeme a naalokujeme si pole pro jednotlivé barevné kanaly RGB:
private int[] histogram = new int[256]; // hodnoty 0 až 255
private int[] redHistogram = new int[256];
private int[] greenHistogram = new int[256];
private int[] blueHistogram = new int[256];
3. V metodě vytvorHistogram() si tato pole vynulujeme:
for (int i = 0; i < histogram.length; i++) {
histogram[i] = 0;
redHistogram[i] = 0;
greenHistogram[i] = 0;
blueHistogram[i] = 0;
}
4. Nyní vypočítáme hodnoty jasů jednotlivých kanálu a naplníme jimy pole:
if (obrazek != null) {
for (int x = 0; x < obrazek.getWidth(); x++) {
for (int y = 0; y < obrazek.getHeight(); y++) {
red = ((obrazek.getRGB(x, y)) & 0xFF0000) >> 16;
redHistogram[red]++;
green = ((obrazek.getRGB(x, y)) & 0xFF00) >> 8;
greenHistogram[green]++;
blue = ((obrazek.getRGB(x, y)) & 0xFF);
blueHistogram[blue]++;
jas = (int) Math.round((red * 0.299) + (green * 0.587) + (blue * 0.114));
histogram[jas]++;
}
}
}
Jak vidíte, vždy vypočítáme hodnotu jasu kanálu, tu najdeme v polu (resp. pouzijeme hodnotu jako index pole) a na tomto indexu inkrementujeme hodnotu o 1. Krome barevných kanálů taky počítáme jas pro histogram v odstinech šedi, využíváme k tomu převod za pomoci vynasobeni kanálů konstantou.
5. Nyní již nezbývá než histogram vykreslit, nejdříve však nesmíme zapomenout zavolat metodu vytvorHistogram()
vytvorHistogram();
if (obrazek == null) {
} else {
Deklarujeme si proměnné:
int maximum = histogram[0];
float pomer;
int prepocitanaCetnost;
int predchoziPrepocitanaCetnost;
Najdeme maximum z pole histogramu, je důležité k vypočítání poměru vypočítaných hodnot vzhledek ke kreslícímu plátnu.
for (int i = 0; i < histogram.length; i++) {
if (maximum < histogram[i]) {
maximum = histogram[i];
}
}
Zjistíme si onen zmiňovaný poměr
pomer = (float) getHeight() / maximum;
Přepočítaná četnost nám slouží k vypočítání hodnoty konkrétního sloupce vzhledem k velikosti zobrazovacího plátna.
Dále již jen vykreslujeme za pomocí cyklů jednotlivé barevné kanály.
for (int i = 0; i < histogram.length; i++) {
g.setColor(Color.BLACK);
prepocitanaCetnost = Math.round(histogram[i] * pomer);
g.drawLine(i + 1, getHeight() - 1, i + 1, getHeight() - 1 - prepocitanaCetnost);
if (i > 0) {
g.setColor(Color.RED);
prepocitanaCetnost = Math.round(redHistogram[i] * pomer);
predchoziPrepocitanaCetnost = Math.round(redHistogram[i - 1] * pomer);
g.drawLine(i, getHeight() - 1 - predchoziPrepocitanaCetnost, i + 1, getHeight() - 1 - prepocitanaCetnost);
g.setColor(Color.GREEN);
prepocitanaCetnost = Math.round(greenHistogram[i] * pomer);
predchoziPrepocitanaCetnost = Math.round(greenHistogram[i - 1] * pomer);
g.drawLine(i, getHeight() - 1 - predchoziPrepocitanaCetnost, i + 1, getHeight() - 1 - prepocitanaCetnost);
g.setColor(Color.BLUE);
prepocitanaCetnost = Math.round(blueHistogram[i] * pomer);
predchoziPrepocitanaCetnost = Math.round(blueHistogram[i - 1] * pomer);
g.drawLine(i, getHeight() - 1 - predchoziPrepocitanaCetnost, i + 1, getHeight() - 1 - prepocitanaCetnost);
}
}
}
}
Žádné komentáře