1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : equalize image filter.
9
* Copyright (C) 2005-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
24
#include "equalizefilter.h"
38
#include "imagehistogram.h"
43
EqualizeFilter::EqualizeFilter(DImg* orgImage, const DImg* refImage, QObject* parent)
44
: DImgThreadedFilter(orgImage, parent, "EqualizeFilter"),
50
EqualizeFilter::~EqualizeFilter()
54
void EqualizeFilter::filterImage()
57
m_destImage = m_orgImage;
60
/** Performs an histogram equalization of the image.
61
this method adjusts the brightness of colors across the
62
active image so that the histogram for the value channel
63
is as nearly as possible flat, that is, so that each possible
64
brightness value appears at about the same number of pixels
65
as each other value. Sometimes Equalize works wonderfully at
66
enhancing the contrasts in an image. Other times it gives
67
garbage. It is a very powerful operation, which can either work
68
miracles on an image or destroy it.*/
69
void EqualizeFilter::equalizeImage()
71
struct double_packet high, low, intensity;
72
struct double_packet* map;
73
struct int_packet* equalize_map;
77
if (m_orgImage.sixteenBit() != m_refImage.sixteenBit())
79
kDebug() << "Ref. image and Org. has different bits depth";
83
// Create an histogram of the reference image.
84
ImageHistogram *histogram = new ImageHistogram(m_refImage.bits(), m_refImage.width(),
85
m_refImage.height(), m_refImage.sixteenBit());
86
histogram->calculate();
89
map = new double_packet[histogram->getHistogramSegments()];
90
equalize_map = new int_packet[histogram->getHistogramSegments()];
92
if( !histogram || !map || !equalize_map )
101
delete [] equalize_map;
103
kWarning() << ("Unable to allocate memory!");
107
// Integrate the histogram to get the equalization map.
109
memset(&intensity, 0, sizeof(struct double_packet));
110
memset(&high, 0, sizeof(struct double_packet));
111
memset(&low, 0, sizeof(struct double_packet));
113
for(i = 0 ; !m_cancel && (i < histogram->getHistogramSegments()) ; ++i)
115
intensity.red += histogram->getValue(RedChannel, i);
116
intensity.green += histogram->getValue(GreenChannel, i);
117
intensity.blue += histogram->getValue(BlueChannel, i);
118
intensity.alpha += histogram->getValue(AlphaChannel, i);
122
// Stretch the histogram.
125
high = map[histogram->getHistogramSegments()-1];
126
memset(equalize_map, 0, histogram->getHistogramSegments()*sizeof(int_packet));
128
// TODO magic number 256
129
for(i = 0 ; !m_cancel && (i < histogram->getHistogramSegments()) ; ++i)
131
if(high.red != low.red)
132
equalize_map[i].red = (uint)(((256*histogram->getHistogramSegments() -1) *
133
(map[i].red-low.red))/(high.red-low.red));
135
if(high.green != low.green)
136
equalize_map[i].green = (uint)(((256*histogram->getHistogramSegments() -1) *
137
(map[i].green-low.green))/(high.green-low.green));
139
if(high.blue != low.blue)
140
equalize_map[i].blue = (uint)(((256*histogram->getHistogramSegments() -1) *
141
(map[i].blue-low.blue))/(high.blue-low.blue));
143
if(high.alpha != low.alpha)
144
equalize_map[i].alpha = (uint)(((256*histogram->getHistogramSegments() -1) *
145
(map[i].alpha-low.alpha))/(high.alpha-low.alpha));
151
uchar* data = m_orgImage.bits();
152
int w = m_orgImage.width();
153
int h = m_orgImage.height();
154
bool sixteenBit = m_orgImage.sixteenBit();
157
// Apply results to image.
158
// TODO magic number 257
159
if (!sixteenBit) // 8 bits image.
161
uchar red, green, blue, alpha;
164
for (i = 0 ; !m_cancel && (i < size) ; ++i)
171
if(low.red != high.red)
172
red = (equalize_map[red].red)/257;
174
if(low.green != high.green)
175
green = (equalize_map[green].green)/257;
177
if(low.blue != high.blue)
178
blue = (equalize_map[blue].blue)/257;
180
if(low.alpha != high.alpha)
181
alpha = (equalize_map[alpha].alpha)/257;
189
progress = (int)(((double)i * 100.0) / size);
190
if ( progress%5 == 0 )
191
postProgress( progress );
194
else // 16 bits image.
196
unsigned short red, green, blue, alpha;
197
unsigned short* ptr = (unsigned short *)data;
199
for (i = 0 ; !m_cancel && (i < size) ; ++i)
206
if(low.red != high.red)
207
red = (equalize_map[red].red)/257;
209
if(low.green != high.green)
210
green = (equalize_map[green].green)/257;
212
if(low.blue != high.blue)
213
blue = (equalize_map[blue].blue)/257;
215
if(low.alpha != high.alpha)
216
alpha = (equalize_map[alpha].alpha)/257;
224
progress = (int)(((double)i * 100.0) / size);
225
if ( progress%5 == 0 )
226
postProgress( progress );
230
delete [] equalize_map;
233
} // namespace Digikam