Decoding Keyence LJ-X8000 Bitmap-Height Image - matlab

I have a Keyence Line Laser System LJ-X 8000, that I use to scan the surface of different objects.
The Controller saves the height information as a bitmap, with each pixel representing one height value. After a lot of tinkering, I found out, that Keyence is not using the actual colors, rather than using the 24-Bit RGB-triplets as some form of binary storage. However, no combination of these bytes seems to work for me. Are there any common storage methods for 24-bit Integers?

To decode those values, I did a scan covering the whole measurement range of the scanner, including some out of range values in the beginning and the end. If you look at the distribution of the values of each color plane, you can see, that the first and third plane actually only use values up to 8/16 which means only 3/4 Bits. This is also visible in the image itself, as it mainly shows a green color.
I concluded that Keyence uses the full byte of the green color plane, 3 Bits of the first and 4 Bits of the last plane to store the height information. Keyence seems to have chosen some weird 15 Bit Integer Format to store their data.
With a little bit-shifting and knowing that the scanner has a valid range from [-2.2, 2.2], I was able to build the following simple little (Matlab-) script to calculate the height information for each pixel:
HeightValBin = bitshift(scanIm(:,:,2),7, 'uint16') ...
+ bitshift(scanIm(:,:,1),4, 'uint16')...
+ bitshift(scanIm(:,:,3),0, 'uint16');
scanBinValScaled = interp1([0,2^15], [-2.2, 2.2], double(scanBinVal));
Keyence offers a software to convert those .bmp into .csv-files, but without an API to automate the process. As I will have to deal with a lot of these files I needed to automate this process.
The calculated values from the rgb triplets are actually even more precise than the exported csv, as the csv only shows 4 digits after the decimal point.

Related

How to overwrite part of a png?

Given a png image and a set of data to write to it, is it possible to overwrite pixels in the existing png in a particular area of interest? For example, If I have a block of data in a rectangle between pixels (0,0) (5,10) would it be possible to write this data as a block into a 10X10 png without any concern for the area not being overwritten? My use case is that I have map tiles where half the data will be in one tile and half in the other, with the blank pixels being white squares. I would like to combine them by simply writing the non-white pixels directly to the existing png in a block without having to open, combine, then re-write the entire png. Does the structure of a png allow this?
I'm loath to claim that this is impossible, but it is certainly complicated.
First of all, pixels of a PNG are (sometimes) interlaced, so you'd have to calculate the locations of your target pixels based on the Adam7 scheme.
Furthermore each row is independently filtered, so you'd have to transform each row of your source using the filter of the target row. Depending on the filter you'd also have to adjust additional bytes on the border of the updated target bytes. Straight from the horse's mouth:
Though the concept is simple, there are quite a few subtleties in the actual mechanics of filtering.
Finally, all the filtered bytes are compressed using a generic compression algorithm called "deflate." Unless you want to decompress the whole thing beforehand, you need to make sure both that (1) your source data can be properly decoded and (2) the bytes near the border of the target bytes are properly compressed in the context of their new neighbors.
I'm not a compression expert, so I won't argue in more detail. One piece of good news is that the algorithm seems to preserve independence between distant regions due to its sliding window scheme: data are only compressed based on data in some preceding range, say 13,000 bytes.
If this seems at all easy to you, give it a try. If you're like me, though, you'll just decode the whole thing, overwrite the pixels as bitmap data, and encode the result.
This is practically impossible because the pixels data (after a row-by-row "filtering") is compressed with ZLIB. And it's practically impossible to change part of a compressed stream.

How to extract LBP features from facial images in MATLAB?

I'm not familiar with Local Binary Pattern (LBP), could anyone help me to know how to extract LBP features from facial images (I need a simple code example)?
While searching, I found this code, but I didn't understand it.
So first of all you need to split the face into a certain amount of
sections.
For each of these sections you then have to loop through the all of
the pixels contained within that section and get their value (grey scale or colour values).
For each pixel check the value of the pixels which border it in (diagonals and up down left and right) and save them
for each of the directions check if the colour value of. if the colour is greater than the original pixels value you can assign that value a 1 and if it is less you can assign it as a 0.
you should get a list of 1's and 0's from the previous steps. put these numbers together and it will be a large binary number, you should be able to convert this to decimal and you will have a number assigned for that pixel. save this number per pixel.
after you have got a decimal number for each pixel within a section you can average all of the values to get an average number for this section.
This may not be the best description of how this works so here is a useful picture which might help you.
There is an extractLBPFeatures function in the R2015b release of the Computer Vision System Toolbox for MATLAB.

Trying to understand how 1-bit BMP image is drawn

As can be seen in this example, each channel (R, G, B) in a BMP file takes an input. A 24-bit BMP image has 8 bit for-R , 8-bit for G, and 8 bit for B. I saved an image in MS-paint as monochrome(black and white). Its property says the image's depth is 1-bit. The question is who gets this 1 bit: R , G or B? Is it not mandatory that all the three channels must get certain value? I am not able to understand how MS-Paint has drawn this BMP image using 1 bit.
Thanks in advance for your replies.
There's multiple ways to store a bitmap. In this case, the important distinction is RGB versus indexed.
In an RGB bitmap, every pixel is associated with three separate values, one for red, another for green, and another for blue. Depending on the "bitness" (bit depth) and the specific pixel format, the different colour channels can have different amount of bits allocated for them - the simplest case is the typical true-color with 8 bits for each of the channels, and another 8 bits (optional) for the alpha channel. However, some pixel formats allocate a bit differently - the idea is that the human eye has different sensitivity to each of those channels, and you can save up on space and improve visual quality by allocating the bits in a smarter way. For example, one of the more popular pixel formats is BGR-565 - that is, 16 bits total, 5 bits for blue, 6 bits for green and 5 bits for red.
In an indexed bitmap, the value stored with each of the pixels is an index (hence "indexed bitmap") into a palette (a colour table). The palette is usually a simple table of colours, using RGB "pixel" formats to assign each index with some specific colour. For example, index 0 might mean black, 1 might mean turqouise etc.
In this case, the bit-depth doesn't exactly map into colour quality - you're not trying to map the whole colour space, you're focusing on some subset of the possible colours instead. For example, if you have 256 shades of grey (say, from black to white), a true-colour bitmap would need at least three bytes per pixel (and each of those three bytes would have the same value), while you could use an indexed bitmap with a pallete of all the grey colours, requiring only one byte per pixel (plus the cost of the pallete - 256 * 3 bytes). There's a lot of benefits to using indexed bitmaps, and a lot of tricks to improve the visual quality further without using more bits-per-pixel, but that would be way beyond the scope of this question.
This also means that you only need as many possible values as you want to show. If you only need 16 different colours, you only need four bits per pixel. If you only need a monochromatic bitmap (that is, either a pixel is "on", or it's "off"), you only need one bit per pixel - and that's exactly your case. If you have the amount of distinct colours you need, you can easily get the required bit depth by taking a base-2 logarithm (e.g. log 256 = 8).
So let's say you have an image that only uses two colours - black and white. You'll build a pallete with two colours, black and white. And for each of the pixels in the bitmap, you either save 0 if it's black, or 1 if it's white.
Now, when you want to draw a bitmap like this, you simply read the palette (0 -> RGB(0, 0, 0), 1 -> RGB(1, 1, 1) in this case), and then you read one pixel after another. If the bit is zero, paint a black pixel. If it's one, paint a white pixel. Done :)
No, it depends on the type of data you chose to save as. Because you chose to save as monochrome, the RGB mapping is not used here, and the used mapping would go as a one byte per pixel, ranging from white to black.
Each type has its own mapping ways, saving as 24-bit will give you RGB mapping, saving as 256 will map a byte for each pixel, each value represents a color( you can find the table on the internet), as for monochrome, you'll have the same as a 256 bitmap, but the color table will only have white and black colors.
Sorry for the mistake, the way I explained for monochrome is actually used by Gray Scale, the monochrome uses one bit to indicate if the pixel is black or white, depending on the value of each bit, no mapping table is used.

How does one embed a file inside of an image? iOS iPhone

There is an app on the app store called active photo (http://itunes.apple.com/us/app/active-photo/id366798464?mt=8) that allows you to embed a hidden image or .exe file inside of an image. I would like to know how to do this regrading adding images to images, kinda like sub images in the original image.
I've been looking into metadata but no tag seems to be big enough to hold an NSData representation of the second picture.
How would one go about adding any type of file to an image, either through embedding or metadata, that would allow the image to be sent though email and or text message and still retain the data?
Thank you.
This is known as steganography.
I would imagine the simplest way of hiding a file inside a JPEG image is just to alter its pixel data in such a way that the compression doesn't damage it but is subtle enough that an interceptor can't detect the hidden data.
I don't think it is possible with JPEG because it's a lossy compression so you would end up corrupting the embedded file. But PNG uses a compression method similar to Deflate, which is loseless.
I have started writing a program like this. The idea was to hide bytes of data by splitting them into the least significant bits of pixels' color channels. Let me do some examples.
An RGB-8 image represents a pixel with 3 bytes, one for red, one for green and one for blue. I store 3 bits into red channel, two into green (human eye is more sensitive to green color) and 3 into blue. So I embed one byte per pixel. Similarly with RGBA-8 image I do 2-2-2-2. This of course involves some bitwise operations.
Things become more interesting with RGB(A)-16 images, where there are two bytes per channel. I use the entire least significant byte of every channel with minimal distortion (worst case 255 / 65535 = ~3.9%) and store up to 3 or 4 bytes of data per pixel. Not bad!!
Moreover there are no complex bitwise operations in this case, a single assignement does the job.
There are lot of improvement to it. I thought to ask the user a password, hash it and seed a secure pseudo random number generator, then no longer move pixel by pixel but instead asking the generator for a new random index.
The drawback of this solution is that the more data has already been embedded, the slower it becomes, because the generator will give more and more occupied indices. But it is much more secure in this way. To make it even more safer I thought to introduce noise data in the untouched pixels, in order to hide the positions of the true data.
As you can see you can do a lot with PNG images! If you are interested I can give the code I wrote so far.

iOS 256 Colors (VGA) to RGB

I'd like to convert a VGA color (256 colors; 8 bit) to a RGB color on iOS.
Is it possible to compute this or do I have to use color tables (using CGColorSpaceCreateIndexed).
UIColor does not support 256 Colors.
Thanks :)
Somewhere, the title you're porting should have set the palette. On the VGA, the 256 colours are mapped through a table that the programmer has previously set to convert them into 18 bit RGB colour (at a uniform 6 bits per channel). If you're running the original title through emulation then watch for writes to ports 0x3c6, 0x3c8 and 0x3c9 or calls to the BIOS via int 10h, with ax = 0x1010 (to set a single colour) or 0x1012 (to set a range). If you have the original code, obviously look for the source of the palette table.
In drawing terms, you can keep the palette yourself, for example as a C-style array of 256 CGColorRefs, or use CGColorSpaceCreateIndexed as you suggest (ignore Apple's slight documentation error; the colour table can contain up to 256 entries, not up to 255) probably with a bitmap context to just pass your buffer off to CoreGraphics and forget about it.
I expect the remapping will be performed on the CPU, so if that gets a bit too costly then consider using GL ES 2.x and writing a suitable pixel shader — you'd upload your actual image as, say, a luminance (ie, single channel) texture, plus a 256x1 texture where the colour at each spot is a palette entry, then write a shader that reads from the first texture for the current texture coordinates and uses that value to index the second.