Histogram Stretch - Image Processing
Bokwon Yoon's Homepage
Home   Image processing   Fractal   Software   Game   Related links
Histogram Stretch

In many cases, bad image contrast arises when the range of an image's brightness levels is not over the whole brightness scale. as shown in the following figure.

In those cases, one can improve the image contrast by stretching the original image's brightness levels.
You determine the minimum and maximum value of the image data and match them to the most dark and bright color pixel values.
The following figure shows the result of histogram stretching applied to the above image.

The following source code shows the details of this algorithm in the form of a plug-in for IntelligentView.

Download the plug-in(SelectedStrectch.dll).

How to run Plug-In

#include "../IVPlugIn.h" /* export function to give the name of the plug-in */ __declspec(dllexport) char *PlugInName() { return "Selected Area Atretch"; /* name of the plug-in */ } /* main plug-in export function flags : DIRECT_RUN, when plug-in is run from "Run Plug-In" menu item MENU_RUN, when it is run after installed ps : plug-in server */ __declspec(dllexport) void PlugInMain(int flags, PLUGINSERVER ps) { HMATRIX Data; /* image data handle */ HMATRIX Bmp; /* image bitmap bits handle */ HIMAGE Image; /* image handle */ IMAGEWINDOW ImgWnd; /* image window handle */ int Width, Height; /* variables for the width and the height of the image */ int Flags; /* variable for image data type */ int i, j; double x, Min,Max, a, b; ivConnectPlugInServer(ps); /* Place this function before any other plug-in function. */ ImgWnd = ivGetActiveImageWindow(); /* Get the handle of the active image window handle */ /* If the value of ImgWnd is NULL, there is no active window and you stop the plug-in */ if (ImgWnd == NULL) { ivRunMessageDialog("There is no active image window.", "warning", MB_OK | MB_ICONSTOP); return; } Image = ivIWGetImageHandle(ImgWnd); /* Get image handle from the image window handle */ Data = ivIMGetDataHandle(Image); /* Get image data handle from the image handle */ Bmp = ivIMGetBmpBitsHandle(Image); /* Get bitmap bit handle from the image handle */ Flags = ivMTGetFlags(Data); /* Get image data type */ /* If the image data type is binary, 16 colors, or RGB colors, stop the plug-in */ if ((Flags == DATA_BINARY) || (Flags == DATA_4BITS) || (Flags == DATA_RGB) || (Flags == DATA_FCOMPLEX) || (Flags == DATA_DCOMPLEX)) { ivRunMessageDialog("Not proper image data type.", "warning", MB_OK | MB_ICONSTOP); return; } ivIMSelect(Image, TRUE); /* If there is a selected area in the image, turn it on. */ /* Get the width and the height of the selected area. */ Width = ivMTGetWidth(Data); Height = ivMTGetHeight(Data); /* Initialize variables for minimum and maximum image data values */ Min = 1.0e+300; Max = -1.0e+300; /* Determine the minimum and the maximum values of the image data */ for (i = 0; i < Width; i++) { for (j = 0; j < Height; j++) { x = ivMTReal(Data, i, j); if (x < Min) Min = x; if (x > Max) Max = x; } } if ((Max-Min) < 1.0e-13) { /* If the minimum is equal to the maximum, replace al pixels by one color. */ for (i = 0; i < Width; i++) { for (j = 0; j < Height; j++) { ivMTSetRealInt(Bmp, i, j, 128); } } } else { /* Otherwise, stretch to 256 colors. */ a = 256.0/(Max-Min); b = -a*Min; for (i = 0; i < Width; i++) { for (j = 0; j < Height; j++) { x = ivMTReal(Data, i, j); ivMTSetRealInt(Bmp, i, j, (int)(a*x+b)); } } } ivIMSelect(Image, FALSE); /* Turn off the area selection. */ ivIWRepaint(ImgWnd, NULL, FALSE); /* Repaint image window. */ }

You can reach me by e-mail at : yoon@agr.lac.u-psud.fr


(c) 1998, Bokwon YOON