-
Path: news-archive.icm.edu.pl!news.gazeta.pl!not-for-mail
From: Mateusz Ludwin <n...@s...org>
Newsgroups: pl.rec.foto.cyfrowa
Subject: Re: hdr a Jpg
Date: Thu, 12 Mar 2009 15:04:17 +0100
Organization: "Portal Gazeta.pl -> http://www.gazeta.pl"
Lines: 358
Message-ID: <gpb4p0$ds9$1@inews.gazeta.pl>
References: <f...@a...googlegroups.com>
<gpaptq$180m$1@alfa.ceti.pl> <gpaqfn$jnr$1@inews.gazeta.pl>
<gpb2r1$1fls$1@alfa.ceti.pl> <gpb3o7$6o1$2@atlantis.news.neostrada.pl>
NNTP-Posting-Host: static-62-233-162-148.devs.futuro.pl
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-2; format=flowed
Content-Transfer-Encoding: 8bit
X-Trace: inews.gazeta.pl 1236866656 14217 62.233.162.148 (12 Mar 2009 14:04:16 GMT)
X-Complaints-To: u...@a...pl
NNTP-Posting-Date: Thu, 12 Mar 2009 14:04:16 +0000 (UTC)
X-User: matl
In-Reply-To: <gpb3o7$6o1$2@atlantis.news.neostrada.pl>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13)
Gecko/20080313 SeaMonkey/1.1.9
Xref: news-archive.icm.edu.pl pl.rec.foto.cyfrowa:796311
[ ukryj nagłówki ]Jakub Jewuła wrote:
> Mateuszu, czekamy na blyskotliwa ropiste ;))))))
Jadziem:
public class GradientCompressionTonemapper implements IToneMapper {
private static final Logger log =
Logger.getLogger(GradientCompressionTonemapper.class
.toString());
private int levels = 3;
private double alpha = 0.1;
private double beta = 0.5;
private int iterations = 500;
private double omega = 1.3;
BufferedImage lastToneMap;
private double s = 0.3;
public BufferedImage generateToneMap(HDRImage sourceImage) {
double[][][] rawData = sourceImage.getRawData();
double[][] luminanceMap = JHDRIUtils.getLogLuminanceMap(sourceImage);
double[][] attenuation = getAttenuation(luminanceMap, 1, getLevels(),
alpha, beta);
double[][][] gradient = getGradient(luminanceMap, attenuation);
double[][] div = getDiv(gradient);
double[][] image = getImage(div);
int width = image.length;
int height = image[0].length;
lastToneMap = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
JHDRIUtils.normalize(image);
double maxLum = JHDRIUtils.getMaxChannelIntensity(sourceImage);
double minLum = JHDRIUtils.getMinChannelIntensity(sourceImage);
luminanceMap = JHDRIUtils.getLuminanceMap(sourceImage);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
// double ch = (int) (255 * ((image[x][y] - min) / (max -
min)));
int r = getColour(rawData[x][y][0], luminanceMap[x][y],
image[x][y], s);
int g = getColour(rawData[x][y][1], luminanceMap[x][y],
image[x][y], s);
int b = getColour(rawData[x][y][2], luminanceMap[x][y],
image[x][y], s);
lastToneMap.setRGB(x, y, b | (g << 8) | (r << 16) | 0xFF000000);
}
}
return lastToneMap;
}
private int getColour(double cIn, double lIn, double lOut, double s) {
double tmp = cIn / lIn;
tmp = Math.pow(tmp, s);
tmp *= lOut;
if (tmp > 1.0) {
tmp = 1.0;
}
if (tmp < 0.0) {
tmp = 0.0;
}
return (int) (255 * tmp);
}
public BufferedImage generateToneMap(HDRImage sourceImage, Rectangle rect) {
throw new UnsupportedOperationException("Not supported yet.");
}
private double[][] getAttenuation(double[][] luminanceMap, int level, int
maxLevel, double alpha, double beta) {
int width = luminanceMap.length;
int height = luminanceMap[0].length;
double[][] attenuationMap = new double[width][height];
double[][] gradientMap = new double[width][height];
double divider = Math.pow(2.0, level);
double mean = 0.0;
for (int x = 1; x < width - 1; x++) {
for (int y = 1; y < height - 1; y++) {
int xp1 = x + 1;
int yp1 = y + 1;
int xm1 = x - 1;
int ym1 = y - 1;
double gx = luminanceMap[xp1][y] - luminanceMap[xm1][y];
double gy = luminanceMap[x][yp1] - luminanceMap[x][ym1];
gx = gx / divider;
gy = gy / divider;
double mag = Math.sqrt(gx * gx + gy * gy);
gradientMap[x][y] = mag;
mean += mag;
}
}
mean = mean / ((double) (width * height));
for (int x = 1; x < width - 1; x++) {
for (int y = 1; y < height - 1; y++) {
double mag = gradientMap[x][y];
attenuationMap[x][y] = Math.pow(mag / (mean * alpha), beta - 1.0);
if (attenuationMap[x][y] > 1.0) {
attenuationMap[x][y] = 1.0;
}
}
}
for (int x = 0; x < width; x++) {
attenuationMap[x][0] = attenuationMap[x][1];
attenuationMap[x][height - 1] = attenuationMap[x][height - 2];
}
for (int y = 0; y < height; y++) {
attenuationMap[0][y] = attenuationMap[1][y];
attenuationMap[width - 1][y] = attenuationMap[width - 2][y];
}
if (level < maxLevel) {
double[][] scaledMap = getAttenuation(scale(luminanceMap, width /
2, height / 2), level + 1, maxLevel, alpha, beta);
scaledMap = scale(scaledMap, width, height);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
attenuationMap[x][y] *= scaledMap[x][y];
}
}
}
return attenuationMap;
}
private double[][][] getGradient(double[][] luminanceMap, double[][]
attenuation) {
int width = luminanceMap.length;
int height = luminanceMap[0].length;
double[][][] gradientMap = new double[width][height][2];
for (int x = 1; x < width - 1; x++) {
for (int y = 1; y < height - 1; y++) {
int xp1 = x + 1;
int yp1 = y + 1;
int xm1 = x - 1;
int ym1 = y - 1;
double gx = luminanceMap[xp1][y] - luminanceMap[xm1][y];
double gy = luminanceMap[x][yp1] - luminanceMap[x][ym1];
gx = gx * attenuation[x][y];
gy = gy * attenuation[x][y];
gradientMap[x][y][0] = gx;
gradientMap[x][y][1] = gy;
}
}
for (int x = 0; x < width; x++) {
gradientMap[x][0] = gradientMap[x][1];
gradientMap[x][height - 1] = gradientMap[x][height - 2];
}
for (int y = 0; y < height; y++) {
gradientMap[0][y] = gradientMap[1][y];
gradientMap[width - 1][y] = gradientMap[width - 2][y];
}
return gradientMap;
}
private double[][] getDiv(double[][][] gradient) {
int width = gradient.length;
int height = gradient[0].length;
double[][] div = new double[width - 1][height - 1];
for (int x = 1; x < width; x++) {
for (int y = 1; y < height; y++) {
div[x - 1][y - 1] = (double) (gradient[x][y][0] - gradient[x -
1][y][0] + gradient[x][y][1] - gradient[x][y - 1][1]);
}
}
return div;
}
private double[][] getImage(double[][] div) {
int width = div.length;
int height = div[0].length;
int n = width * height;
n = iterations;
double[][] image = new double[width][height];
for (int step = 0; step < n; step++) {
log.info("Step: " + step + "/" + n);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
double sigma = 0;
if (x < width - 1) {
sigma += image[x + 1][y];
}
if (x > 0) {
sigma += image[x - 1][y];
}
if (y < height - 1) {
sigma += image[x][y + 1];
}
if (y > 0) {
sigma += image[x][y - 1];
}
image[x][y] = (1 - omega) * image[x][y] + omega * (double)
(-(div[x][y] - sigma) / 4.0);
}
}
}
JHDRIUtils.normalize(image);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image[x][y] = (double) Math.exp(image[x][y]);
}
}
return image;
}
private double[][] scale(double[][] map, int width, int height) {
int mapWidth = map.length;
int mapHeight = map[0].length;
double[][] newMap = new double[width][height];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
double u = ((double) x) / ((double) width);
double v = ((double) y) / ((double) height);
u *= (double) mapWidth;
v *= (double) mapHeight;
int mapX = (int) Math.floor(u);
int mapY = (int) Math.floor(v);
double u_ratio = u - mapX;
double v_ratio = v - mapY;
double u_opposite = 1 - u_ratio;
double v_opposite = 1 - v_ratio;
int mapXp1 = mapX + 1;
int mapYp1 = mapY + 1;
mapX = inBounds(mapX, mapWidth);
mapY = inBounds(mapY, mapHeight);
mapXp1 = inBounds(mapXp1, mapWidth);
mapYp1 = inBounds(mapYp1, mapHeight);
double result = (map[mapX][mapY] * u_opposite +
map[mapXp1][mapY] * u_ratio) * v_opposite +
(map[mapX][mapYp1] * u_opposite + map[mapXp1][mapYp1] *
u_ratio) * v_ratio;
newMap[x][y] = result;
}
}
return newMap;
}
private int inBounds(int val, int max) {
if (val < 0) {
return 0;
}
if (val >= max) {
return max - 1;
}
return val;
}
public int getLevels() {
return levels;
}
public void setLevels(int levels) {
this.levels = levels;
}
public double getAlpha() {
return alpha;
}
public void setAlpha(double alpha) {
this.alpha = alpha;
}
public double getBeta() {
return beta;
}
public void setBeta(double beta) {
this.beta = beta;
}
@Override
public String toString() {
return "Gradient Compression Tonemapper";
}
public int getIterations() {
return iterations;
}
public void setIterations(int iterations) {
this.iterations = iterations;
}
public double getS() {
return s;
}
public void setS(double s) {
this.s = s;
}
}
--
Mateusz Ludwin mateuszl [at] gmail [dot] com
Następne wpisy z tego wątku
- 12.03.09 14:06 Paweł W.
- 12.03.09 14:15 j...@a...at
- 12.03.09 14:16 Paweł W.
- 12.03.09 13:38 Gotfryd Smolik news
- 12.03.09 14:38 Janko Muzykant
- 12.03.09 14:40 Mateusz Ludwin
- 12.03.09 14:41 Stefan Nawrocki
- 12.03.09 14:43 Janko Muzykant
- 12.03.09 14:44 Janko Muzykant
- 12.03.09 14:48 Jakub Jewuła
- 12.03.09 14:43 Stefan Nawrocki
- 12.03.09 14:48 Stefan Nawrocki
- 12.03.09 14:56 Stefan Nawrocki
- 12.03.09 15:04 b...@n...pl
- 12.03.09 15:07 Mateusz Ludwin
Najnowsze wątki z tej grupy
- Trochę NTG - Vegas Pro
- Nikon D5500 i wyzwalanie migawki
- Canon 550D
- EOS 600D i balans bieli w filmach
- EOS 90D i sentymenty
- Skanowanie: Canon MG2550S vs HP OfficeJet 6950
- czas exif a czas modyfikacji pliku
- karta SD po formacie odzyskiwanie zdjęć i filmów
- Chess
- Vitruvian Man - parts 7-11a
- Eltec nie zyje?
- Steve McCurry
- Light - lajkowe klasyki od Chinczykow
- Forum o Sony serii A (alfa)?
- obrobka RAW na konputerze
Najnowsze wątki
- 2024-12-28 Błonie => Analityk Systemów Informatycznych (TMS SPEED) <=
- 2024-12-28 Warszawa => Senior Frontend Developer (React + React Native) <=
- 2024-12-28 Żerniki => Employer Branding Specialist <=
- 2024-12-28 ale zawziętość i cierpliwość
- 2024-12-27 most kilometrowy
- 2024-12-27 Dyplomaci a alkomaty
- 2024-12-27 Zmiana kary
- 2024-12-27 Chiński elektrolizer tester wody
- 2024-12-27 Rzeszów => System Architect (background deweloperski w Java) <=
- 2024-12-27 Kraków => Application Security Engineer <=
- 2024-12-27 Gorzów Wielkopolski => Konsultant wdrożeniowy Comarch XL/Optima (Ksi
- 2024-12-27 Wrocław => Solution Architect (Java background) <=
- 2024-12-27 kladka Zagorze
- 2024-12-27 Poznań => Key Account Manager (ERP) <=
- 2024-12-27 Gdańsk => Full Stack .Net Engineer <=