viewSender Pixel Standout Grayscale Image Text Enhancement Technique Amplifies the differences between foreground and background intensity at the pixel level Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 1 Table of Contents Introduction .................................................................................................................................................. 3 Implementation ............................................................................................................................................ 3 The goal ..................................................................................................................................................... 3 Defining neighbor context area ................................................................................................................ 4 Calculating new pixel values ..................................................................................................................... 4 Border and corner pixels........................................................................................................................... 4 The effect ...................................................................................................................................................... 5 Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 2 Introduction The viewSender pixel standout technique is based in part on the premise that, in grayscale images, text becomes more visible to scanning equipment as the difference between the individual character's foreground color intensity and background color intensity increases. It is also intended to resolve a problem where multiple gradations imposed by image processing techniques to give the appearance of smoothness or roundness to the human eye frustrate a scanner's ability to clearly distinguish character edges and separate characters from one another. To achieve these goals, this technique performs a simple but highly effective algorithm which recalculates individual pixels to an exaggerated relationship with its surrounding context pixels, where the high and low values of the pixels in that context area have been forced to their extremes. Implementation Our source bitmap will be a 256-color grayscale image (this technique can be applied to other pixel types and sizes as long as the values of the pixels represent progressive intensity in either direction). The goal We are going to adjust the values of every pixel in the source image so that its numerical value in comparison to its neighboring pixels is re-factored as though the highest value found among its neighbors is 255, and the lowest value was 0. We will store the resulting pixels in a new image where each pixel in the new image has a one to one correspondence by position to the old image. Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 3 We want to implement our function as a single method that we iteratively apply to each pixel of the source image. We will apply the function left to right, top to bottom as we move through the source image, though any order is acceptable and will produce the same pixels in the resulting image. Defining neighbor context area The first step is to define how many of the pixels adjacent to the one we are modifying are to be considered "neighbor" pixels. We allow the user to supply this value (it must be one or greater). For text character enhancement of 256-color grayscale captured computer screen images at normal screen sizes and resolutions, we've discovered that values between two and six seem to work best. In the example image displayed at the top of this section, we've illustrated using two as the neighbor pixel width. The actual size of the neighbor context area is two times the supplied neighbor width plus one in width, multiplied by two times the supplied neighbor width plus one in height. In this example, the neighbor context area width becomes 5 and the neighbor context area width height also becomes 5, so the total context neighbor area is 25 pixels (of which 24 are "neighbors" - in the example above, neighbor pixels are dark green, the pixel to be modified is light green, and the neighbor context area pixels are framed in red or dark red). Calculating new pixel values For each source pixel in turn, we will check to see if the value of the source pixel is already at the extremes (0 or 255 in our example) - in that case, we simply copy the source pixel to the target and move on. Otherwise, we will interrogate all of the neighbors to see what the highest and lowest values are. If we find out that the lowest value of any of the neighbors is already zero, and the highest value of any of the neighbors is already 255, again, there's nothing more to do for this source pixel - we copy the source pixel to the target and go to the next source pixel. If, however, none of the neighbors was at one or the other extreme, we will use the following formula: byTargetPixel = (BYTE)(((float)255.0 * (float)(bySourcePixel byLowestNeighbor)) / (float)(byHighestNeighbor - byLowestNeighbor)); where byTargetPixel is the calculated replacement pixel for the target image, bySourcePixel is the source pixel's value, byLowestNeighbor is the value of the lowest neighbor pixel, and byHighestNeighbor is the value of the highest neighbor pixel. Border and corner pixels For border and corner pixels, there are no neighbor pixels to supply values for one or more sides of the neighbor context area. In this situation, you can simple choose to use the smaller sample set of the available pixels, or you can supply a (presumably neutral) value to substitute for the missing pixels. In the example at the start of this document, we demonstrate substituting a filler value for missing pixels. We've shown know snapshots of the iterations captured at different points of the processing. Again, light green represents the pixel whose new value we want to calculate, dark green represents pixel values supplied by the source image, and red or dark red bounds the neighbor context pixel area. Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 4 The light gray pixels in the neighbor context area represent the values substituted for the missing pixels (the numbers represent which one of the 486 pixels in the example in the sample is being processed in the neighbor context area). The user supplies the value to be used for substitution - the substituted value would ordinarily be neutral (127 or 128 in our 256-color grayscale example). However, it can also be used to compensate or correct for border pixel problems (pixels already darkened or lightened by sepia toning or curly FAX paper, for example). The effect As a matter of individual characters against a white background, the effect may appear to be subtle to the human eye, even when magnified (the pixel standout version is below): However, in the aggregate against color and graphic backgrounds commonly found on computer screens, the effect is remarkable, and substantially improves the performance of OCR - you can see why in this example taken from the viewSender configuration utility (the second image is processed from the first using pixel standout processing) : Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 5 Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 6 Copyright 2008-2009 F. Scott Deaver - all rights reserved. Proprietary and confidential information, may not be disclosed. Page | 7