How to read no. pixels per res. unit in TIFF header - header

I'm trying to read a TIFF image that has been exported from a Leica (SP5) program. I can read other details (e.g. bits per sample, image size x, image size y) as per tags defined in TIFF documentation. I'm sort of crudely reading the header out as unsigned integers until I get to a certain tag number.
I know at 296, my 'Resolution Unit' is cm. At 282 and 283, it's supposed to give me the number of pixels (in x and y) per resolution unit. I'm not sure how to do this. Can someone please help??

Well, if at 296 you discover what the unit type is (either 1 - No absolute unit, 2 - Inch, or 3 - Centimeter) and at 282 and 283 you get XResolution and YResolution respectively then you have everything you need to solve the problem.
To get a per unit type measure just multiply XResolution and YResolution together:
XResolution * YResolution = PixelsPerUnit
Since you are trying to find the area of the rectangle created by the resolutions.

Related

How to select a lens for reading very small font characters

I am trying to implement an OCR / OCV algorithm for inspecting printed text in black ink on a white background. The text size is ranging from 3 pt. to 6 pt. I tried first to capture images with a 5 MP monochrome camera using an 8 mm, 12 mm and 16 mm lens but I could not get the characters with good clarity. I repeated the same test with 10 MP camera also considering that higher pixel depth will give more information but I got same results.
I'm not sure, how I can get a clearer image. Whether a 5 MP / 10 MP is enough and if there is any way to determine the lens to be used in such application.
The FOV for inspection is about 300 x 250 mm and the working distance I considered from approx. 400 mm to 650 mm.
Due to copyright concerns I cannot post the image of the object under inspection.
Any help or direction is greatly appreciated. Thanks.
It's simple geometry. It is:
3pt =~ 1mm.
Assuming you want to have 10 pixels to cover each character, your IFOV needs to be:
IFOV =~ (font_width / 10) / distance = 0.1 / 650 =~ 0.15 milliradians / pixel.
For the work area width you mention, the horizontal field of view is:
FOV = 2 * atan((300 / 2) / 650) =~ 453 milliradians =~ 26 deg
So the minimal (horizontal) sensor resolution you'd need is:
Width = 453 / 0.15 = 3020 pixels.
Thus a 10MP sensor should be quite sufficient, and 5MP one may be adequate.
To choose the lens, from the above spec for the FOV, and the format (width, height) of your choice of sensor, you can work out by the same simple trigonometry the needed focal length. Finally, among all lenses matching that focal length that are available for your camera mount, you need to choose one that (a) can be focused at the distance of interest and (b) has an adequate Optical Transfer Function such that one line can be resolved at the above IFOV.
In practice, after running the math and looking at catalogs, you'll end up with several candidate lenses. My advice would then be to get samples and try them out on your on setup, and specifically with the particular lighting rig you'll be using, before making a final decision. Depending on your particular project, factors influencing the choice, in addition (obviously) to the cost of the lens + sensor combination, may be size/weight, sensitivity to environment conditions (temperature, humidity, vibrations), availability and lead time for sourcing, etc.

True Type Font Scaling

MSDN's truetype font article (https://learn.microsoft.com/en-us/typography/opentype/otspec160/ttch01) gives the following for converting FUnits to pixels:
Values in the em square are converted to values in the pixel coordinate system by multiplying them by a scale. This scale is:
pointSize * resolution / ( 72 points per inch * units_per_em )
where pointSize is the size at which the glyph is to be displayed, and resolution is the resolution of the output device. The 72 in the denominator reflects the number of points per inch.
For example, assume that a glyph feature is 550 FUnits in length on a 72 dpi screen at 18 point. There are 2048 units per em. The following calculation reveals that the feature is 4.83 pixels long.
550 * 18 * 72 / ( 72 * 2048 ) = 4.83
Questions:
It says "pointSize is the size at which the glyph is to be displayed." How does one compute this, and what units is it in?
It says "resolution is the resolution of the output device". Is this in DPI? Where would I get this information?
It says "72 in the denominator reflects the number of points per inch." Is this related to DPI or no?
In the example, it says '18 point'. Is this 18 used in computing the resolution or the pointSize?
Unfortunately, Apple's documentation is more or less the same, and other than that there are barely any resources other than just reading the source code of stb_truetype.
It says "pointSize is the size at which the glyph is to be displayed." How does one compute this, and what units is it in?
You don’t compute the point size, you set it. It’s the nominal size you want the font to be displayed in (think the font menu in a text editor). The ‘point size’ is a traditional typographical measurement system, with ‘point’ being roughly 1/72 of an inch. This brings the other question:
It says "72 in the denominator reflects the number of points per inch." Is this related to DPI or no?
No. Again, these are typographical points — the same unit you set the point size with. That’s why it’s part of the denominator in the first place: the point size is expressed in a measurement system of 72 points to an inch, and that has to be somehow taken into account in the equation.
Now, the typographical points are different from the output device’s dots or pixels. While in the early days of desktop publishing it was common to have a screen resolution of 72 pixels per inch that indeed corresponded to typographical system of 72 points per inch (no coincidence in that), these days the output resolution can, of course, vary quite dramatically, so it’s important to keep the point vs pixel distinction in mind.
In the example, it says '18 point'. Is this 18 used in computing the resolution or the pointSize?
Neither. It is the point size; see above. The entire example could be translated as follows. With a font based on 2048 units per em, if a particular glyph feature is 550 em units long and the glyph gets displayed at the size of 18 points (that is, 18/72 of an inch) on a device with screen resolution of 72 pixels per inch, the pixel size of that feature will be 4.84.
It says "resolution is the resolution of the output device". Is this in DPI? Where would I get this information?
It’s DPI/PPI, yes. You have to query some system API for that information or just hardcode the value if you’re targeting a specific device.

Identify image depth and print size via Carrierwave, mini-magick and ImageMagick

The goal is to validate an image based on dynamic height and width parameters, as well as DPI.
ImageMagick has the following command Identify which has a number of options.
-density
will generate the geometry widthxheight
-verbose
will generate a helpful "Print size: " and "Resolution"... among 78 other different lines... where width and height need to be parsed out to meet minimum requirements +/- 2%
so how does one extract those into a method, without stepping on intermediate toes (mini-magick)?
As the section on meta-information indicates, MiniMagick accesses the data using ImageMagick function in a single call, for example height density:
image["%y"]
ImageMagick has 47 single-letter attribute percent escapes that allows extraction of the data, provided your call to the image contains a ".path" suffix
image = MiniMagick::Image.open(#yourClass.theColumn.path)

Extra bytes on the end of YUV buffer - RaspberryPi

I've started editing the RaspiStillYUV.c code. I eventually want to process the image I receive, but for now, I'm just working to understand it. Why am I working with YUV instead of RGB? So I can learn something new. I've made minor changes to the function camera_buffer_callback. All I am doing is the following:
fprintf(stderr, "GREAT SUCCESS! %d\n", buffer->length);
The line this is replacing:
bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle);
Now, the dimensions should be 2592 x 1944 (w x h) as set in the code. Working off of Wikipedia (YUV420) I have come to the conclusion that the file size should be w * h * 1.5. Since the Y component has 1 byte of data for each pixel and the U and V components have 1 byte of data for every 4 pixels (1 + 1/4 + 1/4 = 1.5). Great. Doing the math in Python:
>>> 2592 * 1944 * 1.5
7558272.0
Unfortunately, this does not line up with the output of my program:
GREAT SUCCESS! 7589376
That leaves a difference of 31104 bytes.
I figure that the buffer is allocated in fixed size chunks (the output size is evenly divisible by 512). While I would like to understand that mystery, I'm fine with the fixed size chunk explanation.
My question is if I am missing something. Are the extra bytes beyond the expected size meaningful in this format? Should they be ignored? Are my calculations off?
The documentation at this location supports your theory on padding: http://www.raspberrypi.org/wp-content/uploads/2013/07/RaspiCam-Documentation.pdf
Specifically:
Note that the image buffers saved in raspistillyuv are padded to a
horizontal size divisible by 16 (so there may be unused bytes at the
end of each line to made the width divisible by 16). Buffers are also
padded vertically to be divisible by 16, and in the YUV mode, each
plane of Y,U,V is padded in this way.
So my interpretation of this is the following.
The width is 2592 (divisible by 16 so this is ok).
The height is 1944 which is 8 short of being divisible by 16 so an extra 8*2592 are added (also multiplied by 1.5) thus giving your 31104 extra bytes.
Although this kindof helps with the size of the file, it doesn't explain the structure of the YUV output properly. I am having a look at this description to see if this provides a hint to start with: http://en.wikipedia.org/wiki/YUV#Y.27UV420p_.28and_Y.27V12_or_YV12.29_to_RGB888_conversion
From this I believe it is as follows:
Y Channel:
2592 * (1944+8) = 5059584
U Channel:
1296 * (972+4) = 1264896
V Channel:
1296 * (972+4) = 1264896
Giving a sum of :
5059584 + 2*1264896 = 7589376
This makes the numbers add up so only thing left is to confirm if this interpretation is correct.
I am also trying to do the YUV decode (for image comparisons) so if you can confirm if this actually does correspond to what you are reading in the YUV file this would be much appreciated.
You have to read the manual carefully. Buffers are padded to multiples of 16, but colour data is half-size, so your image size needs to be in multiples of 32 to avoid problems with padding breaking external software.

How to change the dpi of differently sized images within a pdf in order to realise a common "print size" for every page?

I am new to the world of raster images, so I will first explain which definitions I use and hope that I will use them right:
- geometry (the total number of pixels of the image %w * %h)
- resolution (pixels per inch / ppi)
- size or "print size" (the display size (e.g. in inches) on screen or printer)
I have some PDF documents containing raster images of different geometry. When opening with evince they therefore all display (and I guess potentially print) with different sizes. I would like to define the print size within the pdf so that evince (or any other viewer) would display every page with the same size when opening the document.
How could this be realized? Geometry and print size of the image are linked by the resolution as far as I understand. Currently one of my pdf's shows to following ImageMagick:identify output:
$identify -units PixelsPerInch -format "%w x %h - %[resolution.x] x %[resolution.y] - %[fx:w/72] x %[fx:h/72] in\n" example.pdf
geometry - resol. - print size -
538 x 375 - 72 x 72 - 7.47 x 5.20 in
546 x 381 - 72 x 72 - 7.58 x 5.29 in
1210 x 1681 - 72 x 72 - 16.80 x 23.34 in
1658 x 1166 - 72 x 72 - 23.02 x 16.19 in
542 x 365 - 72 x 72 - 7.52 x 5.06 in
1673 x 1169 - 72 x 72 - 23.23 x 16.23 in
I would like to realize a constant print size (column 3) and I do not want to change the geometry of the image/ avoid to re-compress it, so that it does not loose quality. In order to proceed it seems to me that I need to understand the following which I cannot find any information about:
1) Which of these three values is actually saved in the pdf document and which one is calculated by identify?
2) Which software (and how) would allow me to batch process a number of pdf files in order to achieve my goal.
3) Guessing that geometry and resol are values of the pdf file and print size is derived from it, the software would need to calculate a resolution value for each image so that print size would qual over all pages?
Thank you very much!
Cheers,
Benjamin
1) I think only the first two are actually stored in the PDF, but the third value (print size) is directly related to resolution (538x375) and pixel density (72ppi aka 72dpi), so it can easily be calculated anyway.
2) It seems like you're going about this a little backward. There are plenty of applications that are perfectly suited to controlling image layout and printing. Adobe Illustrator is one of the most common and there are some free ones, too. But these are going to involve loading the images, visually arranging them on the page and adjusting the print sizes visually, rather than programmatically.
2) If you did want to do this programmatically, though, I think you're going to have a hard time finding software to solve that problem. GIMP and Photoshop both have some batching capability, and I know GIMP has a fairly robust CLI, so you might be able to use that.
3) Yes, you'll start with the print size you want, divide the number of pixels by the number of inches to get ppi/dpi.
NOTE: Keep in mind that dpi goes both directions. If you have a 200 x 300 image and a 400 x 400 image, and you want them both to print 10 inches square, then you're going to distort the 200 x 300 image, stretching it horizontally. The 200 x 300 image will also look poorer quality than the 400 x 400, because you have fewer pixels to work with.
For these and other reasons, I highly recommend a visual approach, rather than a coding approach.
Good luck!