Bernsen Thresholding gamera (8-) - (1-).
Bernsen Thresholding - (. ). .
Bernsen Thresholding. :
bernsen_thres <input_file> <region_size (int)> <contrast_limit (unsigned)> <set_doubt_to_low (bool)>
region_size - . 3 ( 8).
contrast_limit - . 128.
set_doubt_to_low - . 0.
, .
.
( , , - bat- ) :
bernsen_thres (36 )
( 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. */ /* References: &'John Bernsen' "Dynamic thresholding of grey-level images", Proc. 8th International Conference on Pattern Recognition (ICPR8), pp 1251-1255, Paris, France, October 1986. Original author: Øivind Due Trier */ /* Creates a binary image by using the Bernsen algorithm. *region_size* : default = 3 The size of each region in which to calculate a threshold *contrast_limit* : default = 128 The minimum amount of contrast required to threshold. *set_doubt_to_low* : default = 0 The color choice for the doubt pixels */ // 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" //////////////////////////////////////////////////////////////////////////////// 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)); } //////////////////////////////////////////////////////////////////////////////// FIBITMAP* ProcessFilter(FIBITMAP* src_dib, int region_size, unsigned contrast_limit, BOOL set_doubt_to_low) { 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 unsigned x, y, i, j; int k_index; BYTE* src_end_row = src_bits + (height-1) * src_pitch; int end_col = width - 1; BYTE* lines, *linek, *lined; BYTE confused, val, c; BYTE minimum; BYTE maximum; if (set_doubt_to_low) confused = 0; //black else confused = 255; // white for (y = 0; y < height; y++) { lines = src_bits + y * src_pitch; lined = dst_bits + y * dst_pitch; for (x = 0; x < width; x++) { minimum = 255; maximum = 0; // kernel processing for (i = 0; i < region_size; i++) for (j = 0; j < region_size; j++) { linek = lines + (i-1) * src_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; minimum = MIN(minimum, linek[k_index]); maximum = MAX(maximum, linek[k_index]); } c = maximum - minimum; if (c < contrast_limit) val = confused; else { long t = (maximum + minimum) / 2; if (lines[x] >= t) val = 255; // white else val = 0; // black } SetPixel(lined, x, &val); } } // Copying the DPI... FreeImage_SetDotsPerMeterX(dst_dib, FreeImage_GetDotsPerMeterX(src_dib)); FreeImage_SetDotsPerMeterY(dst_dib, FreeImage_GetDotsPerMeterY(src_dib)); 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 != 5) { printf("Usage : bernsen_thres <input_file> <region_size (int)> <contrast_limit (unsigned)> <set_doubt_to_low (int)>\n"); return 0; } FIBITMAP *dib = GenericLoader(argv[1], 0); int region_size = atoi(argv[2]); unsigned contrast_limit = atoi(argv[3]); int set_doubt_to_low = atoi(argv[4]); if (dib) { // bitmap is successfully loaded! if (FreeImage_GetImageType(dib) == FIT_BITMAP) { if (FreeImage_GetBPP(dib) == 8) { FIBITMAP* dst_dib = ProcessFilter(dib, region_size, contrast_limit, set_doubt_to_low); 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; } |
33 . . - , - . - , " ".
, , - , . = 6 - " ". = 1 - .