Abutaleb Thresholding gamera (8-) - (1-).
Abutaleb Thresholding - (. ). .
Abutaleb Thresholding. :
abutaleb_thres <input_file> <region_size (int)>
region_size - ..
, .
.
( , , - bat- ) :
abutaleb_thres (43 )
( FreeImage dll- FreeImage DLL v3.9.2 - . 1. FreeImage).
:
/*
*
* Copyright (C) 2001-2005 Ichiro Fujinaga, Michael Droettboom, and Karl MacMillan
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
________________________________________________________________
bin_ab.c
$Id: threshold.hpp 962 2007-05-21 13:29:29Z cdalitz $
Copyright 1990, Blab, UiO
Image processing lab, Department of Informatics
University of Oslo
E-mail: blab@ifi.uio.no
________________________________________________________________
Permission to use, copy, modify and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that this copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in supporting
documentation and that the name of B-lab, Department of Informatics or
University of Oslo not be used in advertising or publicity pertaining
to distribution of the software without specific, written prior permission.
B-LAB DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL B-LAB
BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
References:
&Ahmed S. Abutaleb
"Automatic thresholding of gray-level pictures using
two-dimensional entropy",
Computer Vision, Graphics, and Image Processing,
vol 47, pp 22-32, 1989.
Original author:
Øivind Due Trier
*/
// This algorithm was taken from the gamera.sf.net sourcecodes
// and adopted for the FreeImage library
//
// Copyright (C) 2007-2008:
// monday2000 monday2000@yandex.ru
#include "FreeImage.h"
#include "Utilities.h"
#include <limits>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
inline void SetPixel(BYTE *bits, unsigned x, BYTE* value)
{ // this function is simplified from FreeImage_SetPixelIndex
*value ? bits[x >> 3] |= (0x80 >> (x & 0x7)) : bits[x >> 3] &= (0xFF7F >> (x & 0x7));
}
////////////////////////////////////////////////////////////////////////////////
void mean_filter(FIBITMAP* src_dib, int region_size, double* p_mean)
{
unsigned width = FreeImage_GetWidth(src_dib);
unsigned height = FreeImage_GetHeight(src_dib);
unsigned pitch = FreeImage_GetPitch(src_dib);
unsigned bpp = FreeImage_GetBPP(src_dib);
unsigned x, y, i, j;
int k_index;
BYTE* src_bits = (BYTE*)FreeImage_GetBits(src_dib); // The image raster
BYTE* src_end_row = src_bits + (height-1) * pitch;
int end_col = width - 1;
BYTE* lines, *linek;
int sum;
unsigned area = region_size * region_size;
for (y = 0; y < height; y++)
{
lines = src_bits + y * pitch;
for (x = 0; x < width; x++)
{
sum = 0;
// kernel processing
for (i = 0; i < region_size; i++)
for (j = 0; j < region_size; j++)
{
linek = lines + (i-1) * pitch;
if (linek < src_bits) linek = src_bits;
if (linek > src_end_row) linek = src_end_row;
k_index = x+j-1;
if (k_index < 0) k_index = 0;
if (k_index > end_col) k_index = end_col;
sum += linek[k_index];
}
p_mean[y*width+x] = (double)sum / area;
}
}
}
////////////////////////////////////////////////////////////////////////////////
FIBITMAP* ProcessFilter(FIBITMAP* src_dib, int region_size)
{
unsigned width = FreeImage_GetWidth(src_dib);
unsigned height = FreeImage_GetHeight(src_dib);
unsigned src_pitch = FreeImage_GetPitch(src_dib);
unsigned bpp = FreeImage_GetBPP(src_dib);
FIBITMAP* dst_dib = FreeImage_Allocate(width, height, 1);
// Build a monochrome palette
RGBQUAD *pal = FreeImage_GetPalette(dst_dib);
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
unsigned dst_pitch = FreeImage_GetPitch(dst_dib);
BYTE* src_bits = (BYTE*)FreeImage_GetBits(src_dib); // The image raster
BYTE* dst_bits = (BYTE*)FreeImage_GetBits(dst_dib); // The image raster
BYTE* lines, *lined;
unsigned x, y;
BYTE val;
int int_size = height*width*sizeof(double);
double* p_average = (double*)malloc(int_size);
memset(p_average,0,int_size);
mean_filter(src_dib, region_size, p_average);
int hw = 256; // square histogram width
int hist_size = hw*hw*sizeof(double);
double* histogram = (double*)malloc(hist_size);
double* P_histogram = (double*)malloc(hist_size);
double* H_histogram = (double*)malloc(hist_size);
memset(histogram,0,hist_size);
memset(P_histogram,0,hist_size);
memset(H_histogram,0,hist_size);
unsigned a, b, s, t;
for (y = 0; y < height; y++)
{
lines = src_bits + y * src_pitch;
for (x = 0; x < width; x++)
{
a = lines[x];
b = p_average[x*width+y];
histogram[a*hw+b] = histogram[a*hw+b] + 1.0;
}
}
double one_over_area = 1.0 / (width * height);
double P_sum, p, H_sum;
for (b = 0; b < 256; b++)
for (a = 0; a < 256; a++)
histogram[a*hw+b] = histogram[a*hw+b] * one_over_area;
P_sum = 0.0;
for (s = 0; s < 256; s++)
{
P_sum += histogram[s*hw];
P_histogram[s*hw] = P_sum;
}
for (t = 1; t < 256; t++)
{
P_sum = 0.0;
for (s = 0; s < 256; s++)
{
P_sum += histogram[s*256+t];
P_histogram[s*hw+t] = P_histogram[s*hw+(t - 1)] + P_sum;
}
}
H_sum = 0.0;
for (s = 0; s < 256; s++)
{
p = histogram[s*hw];
if (p != 0)
H_sum -= p * log(p);
H_histogram[s*hw] = H_sum;
}
for (t = 1; t < 256; t++)
{
H_sum = 0.0;
for (s = 0; s < 256; ++s)
{
p = histogram[s*hw+t];
if (p != 0)
H_sum -= p * log(p);
H_histogram[s*hw+t] = H_histogram[s*hw+(t - 1)] + H_sum;
}
}
double Phi_max = std::numeric_limits<double>::min();
double tiny = 1e-6;
double H_end = H_histogram[255*hw+255];
unsigned threshold = 0, avg_threshold = 0;
double Phi, P, H;
for (s = 0; s < 256; s++)
for (t = 0; t < 256; t++)
{
P = P_histogram[s*hw+t];
H = H_histogram[s*hw+t];
if ((P > tiny) && ((1.0 - P) > tiny))
{
Phi = log(P * (1.0 - P)) + H / P + (H_end - H) / (1.0 - P);
if (Phi > Phi_max)
{
Phi_max = Phi;
threshold = s;
avg_threshold = t;
}
}
}
for (y = 0; y < height; y++)
{
lines = src_bits + y * src_pitch;
lined = dst_bits + y * dst_pitch;
for (x = 0; x < width; x++)
{
if (lines[x] <= threshold && p_average[x*width+y] <= avg_threshold)
val = 0;
else
val = 255;
SetPixel(lined, x, &val);
}
}
// Copying the DPI...
FreeImage_SetDotsPerMeterX(dst_dib, FreeImage_GetDotsPerMeterX(src_dib));
FreeImage_SetDotsPerMeterY(dst_dib, FreeImage_GetDotsPerMeterY(src_dib));
free(p_average);
free(histogram);
free(P_histogram);
free(H_histogram);
return dst_dib;
}
////////////////////////////////////////////////////////////////////////////////
/**
FreeImage error handler
@param fif Format / Plugin responsible for the error
@param message Error message
*/
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
printf("\n*** ");
printf("%s Format\n", FreeImage_GetFormatFromFIF(fif));
printf(message);
printf(" ***\n");
}
////////////////////////////////////////////////////////////////////////////////
/** Generic image loader
@param lpszPathName Pointer to the full file name
@param flag Optional load flag constant
@return Returns the loaded dib if successful, returns NULL otherwise
*/
FIBITMAP* GenericLoader(const char* lpszPathName, int flag)
{
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
// check the file signature and deduce its format
// (the second argument is currently not used by FreeImage)
fif = FreeImage_GetFileType(lpszPathName, 0);
FIBITMAP* dib;
if(fif == FIF_UNKNOWN)
{
// no signature ?
// try to guess the file format from the file extension
fif = FreeImage_GetFIFFromFilename(lpszPathName);
}
// check that the plugin has reading capabilities ...
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
{
// ok, let's load the file
dib = FreeImage_Load(fif, lpszPathName, flag);
// unless a bad file format, we are done !
if (!dib)
{
printf("%s%s%s\n","File \"", lpszPathName, "\" not found.");
return NULL;
}
}
return dib;
}
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
FreeImage_Initialise();
#endif // FREEIMAGE_LIB
// initialize your own FreeImage error handler
FreeImage_SetOutputMessage(FreeImageErrorHandler);
if(argc != 3) {
printf("Usage : abutaleb_thres <input_file> <region_size (int)>\n");
return 0;
}
FIBITMAP *dib = GenericLoader(argv[1], 0);
int region_size = atoi(argv[2]);
if (dib)
{
// bitmap is successfully loaded!
if (FreeImage_GetImageType(dib) == FIT_BITMAP)
{
if (FreeImage_GetBPP(dib) == 8)
{
FIBITMAP* dst_dib = ProcessFilter(dib, region_size);
if (dst_dib)
{
// save the filtered bitmap
const char *output_filename = "filtered.tif";
// first, check the output format from the file name or file extension
FREE_IMAGE_FORMAT out_fif = FreeImage_GetFIFFromFilename(output_filename);
if(out_fif != FIF_UNKNOWN)
{
// then save the file
FreeImage_Save(out_fif, dst_dib, output_filename, 0);
}
// free the loaded FIBITMAP
FreeImage_Unload(dst_dib);
}
}
else
printf("%s\n", "Unsupported color mode.");
}
else // non-FIT_BITMAP images are not supported.
printf("%s\n", "Unsupported color mode.");
FreeImage_Unload(dib);
}
// call this ONLY when linking with FreeImage as a static library
#ifdef FREEIMAGE_LIB
FreeImage_DeInitialise();
#endif // FREEIMAGE_LIB
return 0;
}
|
3 (!) 256 256 .
3 .
2 .
, - , - .
- - .