YUV data in HEX to write into a YUV file - image-processing

I have a typedef structure containing the YUV components that I took from a video frame.
I need to find a way to write these YUV components into a (.YUV) file extension so I could use it for my application in C language.
Does anyone know, How can I can do it?
Best Regards

Well, one of the more common yuv-formats (or rather YCbCr) is YV12
Its is also known as plane-separated 4:2:0 8bpp. Where the 4:2:0 denoted the subsampling used for the color components. 8bpp means the valid range is [0-255] (not realy true, but lets not go there right now...)
It consists of width x height bytes luma-samples (the Y-part) followed by width x height / 4 Cb-data and the same amount of Cr-data. Total number of bytes for one frame is width x height * 3 / 2
So basically all you need to do is to write the Y-component as uint8, followed by Cb-data and Cr-data.
If you need some example code in c to look at, check my yuv-viewer on github.
Hope it helps, if not, drop me a comment.

You will need to learn how to write to a file in binary mode. Take a look at these examples. Once that is clear, all you need to do is dump the hex values of the YUV channels into file.

Related

How to create a custom Dataset for YOLO v3 by LabelImg

I have used LabelImg Save as YOLO option to save my label in the form of .txt with the format like
6 0.333984 0.585938 0.199219 0.160156
But I want it to be in this format
path/to/img1.jpg 50,100,150,200,0 30,50,200,120,3
path/to/img2.jpg 120,300,250,600,2
How do I achieve that?
YOLO uses relative values rather than raw pixel values. In other words, the format is:
center-x center-y width height
Where center-x is the percentage of the width. In other words, if the image is 800px wide, and the center-x is at 400px, the center-x would be written as 0.5.
So your Labellmg values are already correct for training YOLO. Also, in YOLO v3 you do actually need them all to be separate .txt files, rather than in one big long file. So you're already good to go.
Disagree with the above answer. Not all implementations require percentage of width, center or height and the implementations of Yolo I used require a single train.txt file. A specific one for example https://github.com/qqwweee/keras-yolo3 requires exact format mentioned in the question but the 4 numbers are coordinates top right x, top right y, bottom right x, bottom right y followed by class number. Nevertheless you can use those text files and merge them together in a csv including the name of the image in a column as well. This can be done using glob or pandas library. You can do the width, height calculations in the csv for the whole column at once. Then add the path to the complete column at once and convert it into a text file and it will be ready for input.

how to encrypt parts of image in least significant bits of another image?

I want to encrypt some parts of image and embed them into least significant bits of another image.I have pictures in the form of small picturebox in windows forms c#.Can anyone help me with encrypting these blocks?
I doubt it is the correct or fastest way, but likely the easiest way is to just use modulus operator. So for instance if you want to squeeze 2 images into one which has greyscale data in byte format (0-255). For simplicity lets assume you want an even split of 4 bits per image. 2^4=16. So if you take every pixel in that image and mod it:
pic1Pixel = pic1Pixel -pic1Pixel %16
that is going to peel the bottom significance out of that image. Then in the other image do this:
pic2Pixel = floor(pic2Pixel /16)
Do whatever you need to do (casting and floor or whatnot) to ensure the operation happens and then is rounded correctly (language dependent).
Then simply add your two bitmaps pixel by pixel.
compoundPixel = pic1Pixel + pic2Pixel
If after that you want to pull out the first image:
pic1Pixel = 16*(floor(compoundPixel/16))
second image:
pic2Pixel = 16* (compoundPixel%16)
There is almost certainly a cleaner way to do it with simple bit shifting, but I don't feel like debugging/testing anything right now and don't know the sintax off hand. In short though you would just shift in the first 4 bits from first pic then the first 4 bits from the second pic. To recall you would shift out appropriately or mask and normalize.

JPEG2000 : Can number of tiles in X direction be zero?

According to JPEG2000 specs, Number of tiles in X and Y directions is calculated by following formula:
numXtiles =  (Xsiz − XTOsiz)/ XTsiz
&
numYtiles =  (Ysiz − YTOsiz)/ YTsiz
But it is not mentioned about the range of numXtiles or numYtiles.
Can we have numXtiles=0 while numYtiles=250 (or any other value) ?
In short, no. You will always need at least one row and one column of tiles to place your image in the canvas.
In particular, the SIZ marker of the JPEG 2000 stream syntax does not directly define the number of tiles, but rather the size of each tile. Since the tile width and height are defined to be larger than 0 (see page 453 of "JPEG 2000 Image compression fundamentals, standards and practice", by David Taubman and Michael Marcellin), you will always have at least one tile.
That said, depending on the particular implementation that you are using, there may be a parameter numXtiles that you can set to 0 without crashing your program. In that case, the parameter is most likely being ignored or interpreted differently.

Plot an array into bitmap in C/C++ for thermal printer

I am trying to accomplish something a bit backwards from everyone else. Given an array of sensor data, I wish to print a graph plot of it. My test bench uses a stepper motor to move the input shaft of a sensor, stop, get ADC value of sensor's voltage, repeat.
My current version 0.9 bench does not have a graphical output. The proper end solution will. Currently, I have 35 data points, and I'm looking to get 90 to 100. The results are simply stored in an int array. The index is linear, so it's not a complicated plot, but I'm having problems conceptualizing the plot from bottom-left to top-right to display to the operator. I figure on the TFT screen, I can literally translate an origin and then draw lines from point to point...
Worse, I want to also print out this to a thermal printer, so I'll need to translate this into a sub-384 pixel wide graph. I'm not too worried about the semantics of communicating the image to the printer, but how to convert the array to an image.
It gets better: I'm doing this on an Arduino Mega, so the libraries aren't very robust. At least it has a lot of RAM for the code. :/
Here's an example of when I take my data from the Arduino test and feed it into Excel. I'm not looking for color, but I'd like the graph to appear and this setup not be connected to a computer. Or the network. This is the ESC/POS printer, btw.
The algorithm for this took three main stages:
1) Translate the Y from top left to bottom left.
2) Break up the X into word:bit values.
3) Use Bresenham's algorithm to draw lines between the points. And then figure out how to make the line thicker.
For my exact case, the target bitmap is 384x384, so requires 19k of SRAM to store in memory. I had to ditch the "lame" Arduino Mega and upgrade to the ChipKIT uC32 to pull this off, 32k of RAM, 80 MHz cpu, & twice the I/O!
The way I figured out this was to base my logic on Adafruit's Thermal library for Arduino. In their examples, they include how to convert a 1-bit bitmap into a static array for printing. I used their GFX library to implement the setXY function as well as their GFX Bresenham's algorithm to draw lines between (X,Y)s using my setXY().
It all boiled down to the code in this function I wrote:
// *bitmap is global or class member pointer to byte array of size 384/8*384
// bytesPerRow is 384/8
void setXY(int x, int y) {
// integer divide by 8 (/8) because array size is byte or char
int xByte = x/8;
// modulus 8 (%8) to get the bit to set
uint8_t shifty = x%8;
// right shift because we start from the LEFT
int xVal = 0x80 >> shifty;
// inverts Y from bottom to start of array
int yRow = yMax - y;
// Get the actual byte in the array to manipulate
int offset = yRow*bytesPerRow + xByte;
// Use logical OR in case there is other data in the bitmap,
// such as a frame or a grid
*(bitmap+offset)|=xVal;
}
The big point is to remember with an array, we are starting at the top left of the bitmap, going right across the row, then down one Y row and repeating. The gotchya's are in translating the X into the word:bit combo. You've got to shift from the left (sort-of like translating the Y backwards). Another gotchya is one-off error in bookkeeping for the Y.
I put all of this in a class, which helped prevent me from making one big function to do it all and through better design made the implementation easier than I thought it would be.
Pic of the printout:
Write-up of the project is here.

My preallocation of a matrix gives out of memory error in MATLAB

I use zeros to initialize my matrix like this:
height = 352
width = 288
nFrames = 120
imgYuv=zeros([height,width,3,nFrames]);
However, when I set the value of nFrames larger than 120, MATLAB gives me an error message saying out of memory.
The original function is
[imgYuv, S, A]= changeYuv(fileName, width, height, idxFrame, nFrames)
my command is
[imgYuv,S,A]=changeYuv('tilt.yuv',352,288,1:120,120);
Can anyone please tell me what's going on here?
PS: one of the purposes of the function is to load a yuv video which consists more than 2000 frames. Is there any possibility to implement that?
There are three ways to avoid the error
Process a limited number of
frames at any given time.
Work
with integer arrays. Most movies are
in 8-bit format, while Matlab
normally works with doubles.
uint8 takes 1 byte per element,
while double takes 8 bytes. Thus,
if you create your array as B =
zeros(height,width,3,nFrames,'uint8)`,
it only uses 1/8th of the memory.
This might work for 120 frames,
though for 2000 frames, you'll run
again into trouble. Note that not
all Matlab functions work for
integer arrays; you may have to
reimplement those that require
double.
Buy more RAM.
Yes, you (or rather, your Matlab session) are running out of memory.
Get out your calculator and find the product height x width x 3 x nFrames x 8 which will tell you how much memory you have tried to get in your call to zeros. That will be a number either close to or in excess of the RAM available to Matlab on your computer.
Your command is:
[imgYuv,S,A]=changeYuv('tilt.yuv',352,288,1:120,120);
That is:
352*288*120*120 = 1459814400
That is 1.4 * 10^9. If one object has 4 bytes, then you need 6GB. That is a lot of memory...
Referencing the code I've seen in your withdrawn post, your calculating the difference between adjacent frame histograms. One option to avoid massive memory allocation might be to just hold two frames in memory, instead of reading all the frames at once.
The function B = zeros([d1 d2 d3...]) creates an multi-dimensional array with dimensions d1*d2*d3*...
Depending on width and height, given the 3rd dimension of 3 and the 4th dimension of 120 (which effectively results in width*height*360), may result in a very huge array. There are certain memory limits on every machine, maybe you reached these... ;)

Resources