Exprimental feature auto lens distortion correction, on behalf of Guokai; see issue #576

This commit is contained in:
Oliver Duis
2011-03-12 18:45:44 +01:00
parent aded66851e
commit 751dbfd408
38 changed files with 5463 additions and 7 deletions

View File

@@ -913,6 +913,101 @@ void Thumbnail::transformPixel (int x, int y, int tran, int& tx, int& ty) {
ty/=scale;
}
unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width) {
if (!thumbImg)
return NULL;
if (thumbImg->width<trim_width)
return NULL;
// to utilize the 8 bit color range of the thumbnail we brighten it and apply gamma correction
unsigned char* tmpdata = new unsigned char[thumbImg->height*trim_width];
int ix = 0,max;
if (gammaCorrected) {
// if it's gamma correct (usually a RAW), we have the problem that there is a lot noise etc. that makes the maximum way too high.
// Strategy is limit a certain percent of pixels so the overall picture quality when scaling to 8 bit is way better
const double BurnOffPct=0.03; // *100 = percent pixels that may be clipped
// Calc the histogram
unsigned int* hist16 = new unsigned int [65536];
memset(hist16,0,sizeof(int)*65536);
for (int row=0; row<thumbImg->height; row++)
for (int col=0; col<thumbImg->width; col++) {
hist16[thumbImg->r[row][col]]++;
hist16[thumbImg->g[row][col]]+=2; // Bayer 2x green correction
hist16[thumbImg->b[row][col]]++;
}
// Go down till we cut off that many pixels
unsigned long cutoff = thumbImg->height * thumbImg->height * 4 * BurnOffPct;
int max; unsigned long sum=0;
for (max=65535; max>16384 && sum<cutoff; max--) sum+=hist16[max];
delete[] hist16;
scaleForSave = 65535*8192 / max;
// Correction and gamma to 8 Bit
for (int i=0; i<thumbImg->height; i++)
for (int j=(thumbImg->width-trim_width)/2; j<trim_width+(thumbImg->width-trim_width)/2; j++) {
int r= gammatab[MIN(thumbImg->r[i][j],max) * scaleForSave >> 13];
int g= gammatab[MIN(thumbImg->g[i][j],max) * scaleForSave >> 13];
int b= gammatab[MIN(thumbImg->b[i][j],max) * scaleForSave >> 13];
tmpdata[ix++] = r*19595+g*38469+b*7472 >> 16;
}
}
else {
// If it's not gamma corrected (usually a JPG) we take the normal maximum
max=0;
for (int row=0; row<thumbImg->height; row++)
for (int col=0; col<thumbImg->width; col++) {
if (thumbImg->r[row][col]>max) max = thumbImg->r[row][col];
if (thumbImg->g[row][col]>max) max = thumbImg->g[row][col];
if (thumbImg->b[row][col]>max) max = thumbImg->b[row][col];
}
if (max < 16384) max = 16384;
scaleForSave = 65535*8192 / max;
// Correction and gamma to 8 Bit
for (int i=0; i<thumbImg->height; i++)
for (int j=(thumbImg->width-trim_width)/2; j<trim_width+(thumbImg->width-trim_width)/2; j++) {
int r=thumbImg->r[i][j] * scaleForSave >> 21;
int g=thumbImg->g[i][j] * scaleForSave >> 21;
int b=thumbImg->b[i][j] * scaleForSave >> 21;
tmpdata[ix++] = (r*19595+g*38469+b*7472)>>16;
}
}
// histogram equalization
unsigned int hist[256] = {0};
for (int i=0; i<ix; i++) {
hist[tmpdata[i]]++;
}
int cdf = 0, cdf_min=-1;
for (int i=0; i<256; i++) {
cdf+=hist[i];
if (cdf>0 && cdf_min==-1) {
cdf_min=cdf;
}
if (cdf_min!=-1) {
hist[i] = (cdf-cdf_min)*255/((thumbImg->height*trim_width)-cdf_min);
}
}
for (int i=0; i<ix; i++) {
tmpdata[i] = hist[tmpdata[i]];
}
return tmpdata;
}
// format: 1=8bit direct, 2=16bit direct, 3=JPG
bool Thumbnail::writeImage (const Glib::ustring& fname, int format) {