I'm using the TWAIN libraries to scan a greyscale image. I then programmatically adjust each pixel in the scanned image to have different white and black endpoints. So pixels with a colour value of less than the blackpoint are clamped to the blackpoint. And pixels with a colour value of greater than the whitepoint are clamped to the whitepoint. Also, all pixels that are inbetween are extrapolated.
My problem is that I'm losing quality in the calculation because the scanned image I'm doing the calculation on is only 8bits per colour channel.
I either need some way of acquiring the image with a higher number of bits per colour channel, or I need to tell the scanner to do this calculation for me.
I know that the Epson control panel allows you to specify black and white end points and do this calculation, and it looks like it's not having the accuracy issues. So I wonder if it's doing something specific to the Epson hardware. Unfortunately my software needs to use generic printers.
Does anyone know a way around this problem?
Some models of TWAIN scanner - mostly they are flatbeds - can deliver data deeper than 8 bits/channel.
Your code needs to set the transfer mechanism (ICAP_XFERMECH) to memory (TWSX_MEMORY), set the pixel type (ICAP_PIXELTYPE) to TWPT_GRAY, then see if you can set ICAP_BITDEPTH to 16.
If that succeeds, you can then do a memory (AKA buffered) image transfer, and get 16-bit/channel data. I expect you'll find that the data is in the 10-12 upper bits (i.e. the sample range is 0..65535) and the low bits are noise.
You can't use native transfer mode (TWSX_NATIVE) because the native image formats (DIB and PICT) don't support 16-bit/channel data. You might be able to use file transfer mode with a file format that supports 16-bit/channel data, like TIFF or JFIF: You'd just have to experiment with the scanner.
I just did this with an Epson Perfection V100 Photo I have on my desk, I'm sure other Epsons support this, maybe all the Perfection series.
See: Twister Report archive
And yes, the reason this works well with 8-bit scans when you do contrast adjustments in the scanner's UI is that the scanner is adjusting the contrast by tweaking the gain in an amplifier - so working in the analog domain. (Effectively, infinite bits/channel ;-)
You could exploit that circuitry: Most flatbeds will let you set ICAP_SHADOW, ICAP_HIGHLIGHT and ICAP_CONTRAST - which has the same effect as setting the black level, white level and contrast in the scanner UI. Then you'd be adjusting the analog signal, and you'll get dense 8-bit histograms.
Related
I have a problem with the resolution in a PDF file generated on the basis of HTML
I am using HtmlToPdfConverter from Syncfusion together with WebKitConverter
The A4 paper size is set to 595px x 842px
I worked on Windows 7 with an older screen. Everything was fine
When run on a Windows 10 system with a different screen, the paper content is larger than paper. The text is too big, the pictures are too big
The size of the text is also set in pixels.
For sure the difference is in PPI
A code snippet with generator settings:
PdfMargins margins = new PdfMargins();
margins.Left = 50;
margins.Right = 50;
margins.Top = 0;
margins.Bottom = 0;
settings.Margin = margins;
settings.Orientation = PdfPageOrientation.Portrait;
settings.WebKitViewPort = new System.Drawing.Size(595, 0);
settings.PdfPageSize = new SizeF(595, 842);
Is it possible to set in some way that it will always work?
The content size of PDF document may different based on machine/application where the conversion take place. If you need a same output in all the machine/application then please set a fixed viewport size in WebKitViewPort property. WebKit HTML converter internally using system viewport size for converting HTML to PDF. The system viewport size may differs based on the system and application.
Even the fixed WebKitViewPort size does not helps, please provide us the complete code snippet for the conversion, so that it will helpful for us to analyze and assist you further on this.
Please refer below links for more details about WebKit viewport.
UG: https://help.syncfusion.com/file-formats/pdf/convert-html-to-pdf/webkit#viewport
KB: https://www.syncfusion.com/kb/7412/
Note: I work for Syncfusion
Try setting the size in em instead of px for you text sizing. You can set the pictures in percentage. You want to make everything scaled to the paper size.
“Ems” (em): The “em” is a scalable unit that is used in web document
media. An em is equal to the current font-size, for instance, if the
font-size of the document is 12pt, 1em is equal to 12pt. Ems are
scalable in nature, so 2em would equal 24pt, .5em would equal 6pt, etc
Meet the Units
“Ems” (em): The “em” is a scalable unit that is used in web document
media. An em is equal to the current font-size, for instance, if the
font-size of the document is 12pt, 1em is equal to 12pt. Ems are
scalable in nature, so 2em would equal 24pt, .5em would equal 6pt,
etc. Ems are becoming increasingly popular in web documents due to
scalability and their mobile-device-friendly nature.
Pixels (px): Pixels are fixed-size units that are used in screen
media (i.e. to be read on the computer screen). One pixel is equal
to one dot on the computer screen (the smallest division of your
screen’s resolution). Many web designers use pixel units in web
documents in order to produce a pixel-perfect representation of
their site as it is rendered in the browser. One problem with the
pixel unit is that it does not scale upward for visually-impaired
readers or downward to fit mobile devices.
Points (pt): Points are traditionally used in print media (anything
that is to be printed on paper, etc.). One point is equal to 1/72 of
an inch. Points are much like pixels, in that they are fixed-size
units and cannot scale in size.
Percent (%): The percent unit is much like the “em” unit, save for a
few fundamental differences. First and foremost, the current
font-size is equal to 100% (i.e. 12pt = 100%). While using the
percent unit, your text remains fully scalable for mobile devices
and for accessibility.
So, What’s the Difference?
It’s easy to understand the difference between font-size units when you see them in action. Generally, 1em = 12pt = 16px = 100%. When using these font-sizes, let’s see what happens when you increase the base font size (using the body CSS selector) from 100% to 120%
As you can see, both the em and percent units get larger as the base font-size increases, but pixels and points do not. It can be easy to set an absolute size for your text, but it’s much easier on your visitors to use scalable text that can display on any device or any machine. For this reason, the em and percent units are preferred for web document text.
https://kyleschaeffer.com/css-font-size-em-vs-px-vs-pt-vs-percent
I'm trying to investigate an issue I thinking I'm seeing in an application that generates a TIF image.
To do this I'm trying to regenerating\saving the image myself following this msdn Encoder.Compression example (except I'm using CompressionCCITT4).
The output file has a 'Resolution unit' = 2 but I would like to set that to 1.
Questions:
Any ideas how to do set the 'Resolution unit'?
Any ideas on the effect that would\should have on the image?
Thanks!
Disclaimer: Being a Java guy, I don't know how to set it using the library you describe. So I'll only answer question part 2:
Any ideas on the effect that would\should have on the image?
The quick answer is: None. It only matters when you import the image into a page-setting/layout program, word processor, print it, etc. But a lot of software simply assumes 72dpi in both x/y dimensions regardless.
Here's what the TIFF spec says:
Typically, TIFF pixel- editors do not care about the resolution, but applications (such as page layout programs) do care.
And:
1 = No absolute unit of measurement. Used for images that may have a non-square aspect ratio, but no meaningful absolute dimensions.
The drawback of ResolutionUnit=1 is that different applications will import the image
at different sizes. Even if the decision is arbitrary, it might be better to use dots per
inch or dots per centimeter, and to pick XResolution and YResolution so that the aspect ratio is correct and the maximum dimension of the image is about four inches (the “four” is arbitrary.)
I'm trying to develop an image focusing algorithm for some test automation work. I've chosen to use AForge.net, since it seems like a nice mature .net friendly system.
Unfortunately, I can't seem to find information on building autofocus algorithms from scratch, so I've given it my best try:
take image. apply sobel edge detection filter, which generates a greyscale edge outline. generate a histogram and save the standard dev. move camera one step closer to subject and take another picture. if the standard dev is smaller than previous one, we're getting more in focus. otherwise, we've past the optimal distance to be taking pictures.
is there a better way?
update: HUGE flaw in this, by the way. as I get past the optimal focus point, my "image in focus" value continues growing. you'd expect a parabolic-ish function looking at distance/focus-value, but in reality you get something that's more logarithmic
update 2: okay, so I went back to this and the current method we're exploring is given a few known edges (okay, so I know exactly what the objects in the picture are), I do a manual pixel intensity comparison. as the resulting graph gets steeper, I get more in focus. I'll post code once the core algorithm gets ported from matlab into c# (yeah, matlab.. :S)
update 3: yay final update. came back to this again. the final code looks like this:
step 1: get image from the list of images (I took a hundred photos through the focused point)
step 2: find an edge for the object I'm focusing (In my case its a rectangular object that's always in the same place, so I crop a HIGH and NARROW rectangle of one edge)
step 3: get the HorizontalIntensityStatistics (Aforge.net class) for that cropped image.
step 4: get the Histogram (gray, in my case)
step 5: find the derivative of the values of the histogram
step 6: when your slope is the largest, is when you're in the most focused point.
You can have a look at the technique used in the NASA Curiosity Mars Rover.
The technique is described in this article
EDGETT, Kenneth S., et al. Curiosity’s Mars Hand Lens Imager (MAHLI) Investigation. Space science reviews, 2012, 170.1-4: 259-317.
which is available as a PDF here.
Quoting from the article:
7.2.2 Autofocus
Autofocus is anticipated to be the primary method by which MAHLI is
focused on Mars. The autofocus command instructs the camera to move to
a specified starting motor count position and collect an image, move a
specified number of steps and collect another image, and keep doing so
until reaching a commanded total number of images, each separated by a
specified motor count increment. Each of these images is JPEG
compressed (Joint Photographic Experts Group; see CCITT (1993)) with
the same compression quality factor applied. The file size of each
compressed image is a measure of scene detail, which is in turn a
function of focus (an in-focus image shows more detail than a blurry,
out of focus view of the same scene). As illustrated in Fig. 23, the
camera determines the relationship between JPEG file size and motor
count and fits a parabola to the three neighboring maximum file sizes.
The vertex of the parabola provides an estimate of the best focus
motor count position. Having made this determination, MAHLI moves the
lens focus group to the best motor position and acquires an image;
this image is stored, the earlier images used to determine the
autofocus position are not saved.
Autofocus can be performed over the
entire MAHLI field of view, or it can be performed on a sub-frame that
corresponds to the portion of the scene that includes the object(s) to
be studied. Depending on the nature of the subject and knowledge of
the uncertainties in robotic arm positioning of MAHLI, users might
elect to acquire a centered autofocus sub-frame or they might select
an off-center autofocus sub-frame if positioning knowledge is
sufficient to determine where the sub-frame should be located. Use of
sub-frames to perform autofocus is highly recommended because this
usually results in the subject being in better focus than is the case
when autofocus is applied to the full CCD; further, the resulting
motor count position from autofocus using a sub-frame usually results
in a more accurate determination of working distance from pixel scale.
The following is Figure 23:
This idea was suggested also in this answer: https://stackoverflow.com/a/2173259/15485
It may be a bit simplistic for your needs, but I've had good results with a simple algorithm that looks at the difference to neighbouring pixels. The sum of the difference of pixels 2-away seems to be a reasonable measure of image contrast. I couldn't find the original paper by Brenner in the 70's but it is mentioned in http://www2.die.upm.es/im/papers/Autofocus.pdf
Another issue is when the image is extremely out of focus, there is very little focus information, so it's hard to tell which way is 'moving closer' or to avoid a local maximum.
I haven't built one myself, but my first thought would be to do a 2D DFT on a portion of the image. When out of focus, high frequencies will disappear automatically.
For a lazy prototype, You could try to compress a region of the image with JPEG (high quality), and look at the output stream size. A big file means a lot of detail, which in turn implies the image is in focus. Beware that the camera should not be too noisy, and that you can't compare file sizes across different scenes of course.
This might be useful. It's how camera's AF system actually works - Passive Autofocus
Contrast measurement
Contrast measurement is achieved by
measuring contrast within a sensor
field, through the lens. The intensity
difference between adjacent pixels of
the sensor naturally increases with
correct image focus. The optical
system can thereby be adjusted until
the maximum contrast is detected. In
this method, AF does not involve
actual distance measurement at all and
is generally slower than phase
detection systems, especially when
operating under dim light. As it does
not use a separate sensor, however,
contrast-detect autofocus can be more
flexible (as it is implemented in
software) and potentially more
accurate. This is a common method in
video cameras and consumer-level
digital cameras that lack shutters and
reflex mirrors. Some DSLRs (including
Olympus E-420, Panasonic L10, Nikon
D90, Nikon D5000, Nikon D300 in Tripod
Mode, Canon EOS 5D Mark II, Canon EOS
50D) use this method when focusing in
their live-view modes. A new
interchangeable-lens system, Micro
Four Thirds, exclusively uses contrast
measurement autofocus, and is said to
offer performance comparable to phase
detect systems.
While the sobel is a decent choice, I would probably choose to do an edge magnitude calculation on the projections in x and y directions over several small representative regions. Another .NET friendly choices based on OpenCV is # http://www.emgu.com/wiki/index.php/Main_Page.
I wonder if the standard deviation is the best choice: If the image gets sharper, the sobel filter image will contain brighter pixels at the edges, but at the same time fewer bright pixels, because the edges are getting thinner. Maybe you could try using an average of the 1% highest pixel values in the sobel image?
Another flavor for focus metric might be:
Grab several images and average them ( noise reduction).
Then FFT the averaged image and use the high to low frequencies energy ratio.
The higher this ration the better focus. A Matlab demo is available (excluding the averaging stage) within the demos of the toolbox :)
I've been fussing with this for the better part of the night, so maybe one of you can give me a hand.
I have found GDI+ DrawImage in C# to be far too slow for what I'm trying to render, and from the looks of forums, it's the same for other people as well.
I decided I would try using AlphaBlend or BitBlt from the Win32 API to get better performance. Anyway, I've gotten my images to display just fine except for one small detail—no matter what image format I use, I can't get the white background to disappear from my (transparent) graphics.
I've tried BMP and PNG formats so far, and verified that they get loaded as 32bppargb images in C#.
Here's the call I'm making:
// Draw the tile to the screen.
Win32GraphicsInterop.AlphaBlend(graphicsCanvas, destination.X, destination.Y, this.TileSize, this.TileSize,
this.imageGraphicsPointer, tile.UpperLeftCorner.X, tile.UpperLeftCorner.Y,
this.TileSize, this.TileSize,
new Win32GraphicsInterop.BLENDFUNCTION(Win32GraphicsInterop.AC_SRC_OVER, 0,
Convert.ToByte(opacity * 255),
Win32GraphicsInterop.AC_SRC_ALPHA));
For the record, AC_SRC_OVER is 0x00 and AC_SRC_ALPHA is 0x01 which is consistent with what MSDN says they ought to be.
Do any of you guys have a good solution to this problem or know a better (but still fast) way I can do this?
Graphics.DrawImage() speed is critically dependent on the pixel format. Format32bppPArgb is 10 times faster than any other one on any recent machine I've tried.
Also make sure you the image doesn't get resized, be sure to use a DrawImage() overload that sets the destination size equal to the bitmap size. Very important if the video adapter's DPI setting doesn't match the resolution of the bitmap.
Have you tried an opacity of just 255 rather than a calculated one?
This blog post describes what you're trying to do:-
http://blogs.msdn.com/andreww/archive/2007/10/10/preserving-the-alpha-channel-when-converting-images.aspx
Critical thing is that he carries out a conversion of the image to make the alpha channel compatible..
Ok. From a pure Win32 perspective:
In order for AlphaBlend to actually alpha blend... it needs the source device context to contain a selected HBITMAP representing an image with 32bpp bitmap with a pre-multiplied alpha channel.
To get a device bitmap with 32bpp you can either call one of the many functions that will create a screen compatible device bitmap and hope like hell the user has selected 32bpp as the desktop bitdepth. OR, ensure that the source bitmap is a DIBSection. Well, the library or framework that is creating it from the loaded image for you.
So, C# is loading your images with 32bpp argb, BUT, how are you converting that C# representation of the bitmap into a HBITMAP? You need to ensure that a DIB Section is being created, not a DDB (or device dependent bitmap), and that the DIB Section is 32bpp.
At some long-ago Flash conferences I recall seeing a demo of a Flash app that had a color picker. Based on the user's color choice the app would show the user a set of images within the approximate range of that color: a bunch of mostly red images, a bunch of mostly blue images, etc.
I'm looking for two things:
1) A link to a demo of this sort of app, ideally a Flash app
2) ActionScript or C# code that describes how to pick a bunch of images that fall within a color range.
I know how to extract the aggregate/average RGB from individual images and persist this info to a database. I need to know how exactly to select out images within a certain range of color tolerance. Could this be done purely using SQL and a knowledge of the alphanumeric assignments of RGB color codes, or is there a better way?
I could not find any sample code, but found an article that gives a high-level explanation of their process (from this other page about Flickr's feature to search for images with similar colors). Apparently, Google also lets you do this with their image search (but I don't know if that is from metadata tags or actual color matching).
Now to the actual answer:
Instead of just storing the average or aggregate color for an image, you will need to store a "color signature" of the image.
My first (educated guess) idea would entail these steps:
Generate the histogram for each color band from the image
Generate some factors that describe each histogram curve (mean, variance, std-dev, etc? -- these factors will make up your digital signature of your image)
Store those factors in your database (and each of these factors would have an index in the DB)
Then, you would take your input (either a color, range of colors, or source image), run your histogram algorithm against that source, and search for matches to your computed factors.
The Flickr Hacks solution I cite in the comments is the best I've found: it involves resizing the image to 1x1 pixels using common algorithms which gives you an average color for the entire image. Clever.
You can use a set of descriptors for each image, then match those.
There's some great work here on it.. for C#.
http://savvash.blogspot.com/p/compact-composite-descriptors.html
Also check out the free img(Rummager) tool.. which can do what you want(ie find images matched by colour).