LodePng 24bit RGB mode can't understand how to choose - png

I have an YUV 420 (144x176) file from which I read first frame and converted its YUV components to RGB array int rgb[HEIGHT*WIDTH*3]; in which I store R1G1B1...RnGnBn and have an std::vector<unsigned char> image; image.resize(width * height * 4);. My question is:
When I use unsigned error = lodepng::encode(filename, image, width, height); it processes without errors and generates a PNG file, but this file is not even looks like an original image, I think that it uses RGBA while I only have RGB, how to fix it?
P.S. Don't know is this ^ information is enough, so tell me if no, please.

Okay, this question should be closed now.
All I've done is added 255 as Alpha in 4th position, something like this:
if (i%3==0 && i != 0)
image[k++] = 255;
image[k] = rgb[i];
P.S. Another important thing I missed is to put pixels at their real position when reading from YUV file, I mean like shown on Wiki's figure. Note this if you will have problems with YUV.

Related

Why are these red and green squares showing up on my PNG?

I have a VTF file that looks like this inside VTFEdit:
I tried to convert it to a PNG in Python using the code below:
import texture2ddecoder, numpy, cv2
from PIL import Image
img_width = 64
img_height = 64
encoded_binary = open('bracketsTest.vtf','rb').read()
#decompressing dxt5 (compression used for this VTF file) to get actual pixel colors, returns BGRA bytes
decoded_binary = texture2ddecoder.decode_bc5(encoded_binary, img_width, img_height)
#creating RGBA png, converting from BGRA (no support for BRGA in PIL it seems)
dec_img = Image.frombytes("RGBA", (img_width, img_height), decoded_binary, 'raw', ("BGRA"))
dec_img.show()
dec_img.save('testpng.png')
And the resulting image came out like this:
As the resulting image does not look the same as it does in VTFEdit, obviously something went wrong. I suspected that it was an issue with the color channel going from BGRA (VTFs are BRGA by default + texture2ddecoder produces BRGA bytes when decompressing) to RGBA, so I tried the following code to convert the image from RGBA to BRGA:
# trying to convert png back to BGRA
image = cv2.imread('testpng.png')
image_bgra = cv2.cvtColor(image, cv2.COLOR_RGBA2BGRA)
cv2.imshow('image',image_bgra)
But the resulting image came out basically the same as before the conversion only with blue squares instead of red ones. What's going on here and how can I fix it? Is there a name for these odd squares?
DXT5 is actually known as Block Compression 3 (BC3). In my case, I incorrectly assumed BC5 = DXT5, so the decompression was wrong (see this wikipedia article for a better explanation). I changed the line decoded_binary = texture2ddecoder.decode_bc5(encoded_binary, img_width, img_height) to decoded_binary = texture2ddecoder.decode_bc3(encoded_binary, img_width, img_height) and the resulting image looked like this:
There are still some odd squares at the top, but deleting/ignoring the header info and low-res thumbnail data seems to fix it:
Know your decompression algorithms!!!

PIL simple image paste - image changing color

I'm trying to paste an image onto another, using:
original = Img.open('original.gif')
tile_img = Img.open('tile_image.jpg')
area = 0, 0, 300, 300
original.paste(tile_img, area)
new_cropped.show()
This works except the pasted image changes color to grey.
Image before:
Image after:
Is there a simple way to retain the same pasted image color? I've tried reading the other questions and the documentation, but I can't find any explanation of how to do this.
Many thanks
I believe all GIF images are palettised - that is, rather than containing an RGB triplet at each location, they contain an index into a palette of RGB triplets. This saves space and improves download speed - at the expense of only allowing 256 unique colours per image.
If you want to treat a GIF (or palettised PNG file) as RGB, you need to ensure you convert it to RGB on opening, otherwise you will be working with palette indices rather than RGB triplets.
Try changing the first line to:
original = Img.open('original.gif').convert('RGB')

Extracting raw DICOM data from a DICOM file

I am working on a 3D DICOM file. After it is read (using MATLAB, for example) I see that it contains some text information apart from the actual scan image. I mean text which is visible in the image when I do implay(), not the header text in the DICOM file. Is there any way by which I can load only the raw data without the text? The text is hindering my processing.
EDIT: I cannot share the image I'm working on due to it being proprietary, but I found the following image after googling:
http://www.microsoft.com/casestudies/resources/Images/4000010832/image7.jpeg http://www.microsoft.com/casestudies/resources/Images/4000010832/image7.jpeg
Notice how the text on the left side partially overlaps the image? There is a similar effect in the image I'm working on. I need just the conical scan image for processing.
As noted, you need to provide more information, as there are a number of ways the overlay can be added: if it's burned into the image, you're generally out of luck; if it's in the overlay plane module (the 60xx tag group), you can probably just remove those prior to passing into Matlab; if it's stored in the unused high bit (an old but common method), you'll have to use the overlay bit position (60xx,0102) to clear out the data in the pixel data.
For the last one, something like the Matlab equivilent of this Java code:
int position = object.getInt( Tag.OverlayBitPosition, 0 );
if( position == 0 ) return;
// Remove the overlay data in high-bit specified.
//
int bit = 1 << position;
int[] pixels = object.getInts( Tag.PixelData );
int count = 0;
for( int pix : pixels )
{
int overlay = pix & bit;
pixels[ count++ ] = pix - overlay;
}
object.putInts( Tag.PixelData, VR.OW, pixels );
If you refer to the text in the blue area on top of the image, these contents are burned into the image itself.
The only solution to remove that is to apply a mask to this area of the image.
Be careful, because doing this is a modification of the original DICOM image. Such kind of modifications are not allowed in some scenarios.

When I write the image it appears black

I have a program that returns a grayscale image. But, when I try to write the image, it appears totally black. Why is that? How can I write the image and get the expected result?
Thanks.
First check on the type of your data. You can cast the type of the data by example double() or uint16() etc. (Check the help for typecasting).
Here is an example how you rescale your values to the intensity-range of uint16, unsigned integers with ~65k possible different values. The casting of course leads to less precision of the intensity values.
new_img(:,:) = uint16((new_img(:,:)./max(max(new_img(:,:),[],1)))*65536);
Afterwards you should be able to write the data to your file.
Make sure that your grayscaled image is of the right class. Furthermore check the values in the generated image. If they're simply too low all will appear black. If you can provide more specific information it might be possible to give a more elaborate answer.
if you're working on a binary image(before being converted to gray) and you about to convert it to gray-scale, then you suddenly change the range of pixels from [0, 1] to [0, 255]. so the value '1' in binary image is totally white but in gray-scale image is almost black.
try this:
img = imread('image_name.jpg');
imshow(img*50)
it make you sure that you image is black or just its pixel-values aren't appropriate.

The color of video is wrong when made from UIImage of the PNG files

I am taking a UIImage from Png file and feed it to the videoWriter.
avAdaptor appendPixelBuffer:pixelBuffer
When the end result video comes out, it seems to lacking the one color, missing the yellow color or something.
I take alook of the function that made the pixelbuffer out of the UIImage
CVPixelBufferCreateWithBytes(NULL,
myWidth,
myHeight,
kCVPixelFormatType_32BGRA,
(void*)CFDataGetBytePtr(image),
CGImageGetBytesPerRow(cgImage),
NULL,
0,
NULL,
&pixelBuffer);
I also try the kCVPixelFormatType_32AGRB and others, it didn't help.
any thoughts?
Please verify if your PNG image is with or without transparency element. If your PNG image doesn't contain transparency then it's 24-bit and not 32-bit per pixel.
Also, have you tried kCVPixelFormatType_32RGBA ?
Maybe the image sizes do not fit together.
Your input image should have the same width and height like the video output. If "myWidth" or "myHeight" is different (i.e. different aspect ratio) to the size of the image, one byte may be lost at the end of the line, which could lead to color shifting. kCVPixelFormatType_32BGRA seems to be the preferred (fastest) pixel format, so this should be okay.
There is no yellow color in RGB colorspace. This means yellow is only the >red< and >green< components. It seems that >blue< is missing.
I assume you are using a CFDataRef (maybe NSData) for the image. If it is an NSData object you can print the bytes to the debug console using
NSLog(#"data: %#", image);
This will print a hex dump to the console. Here you can see if you have alpha and what kind of byte order your png is alike. If your image has alpha, every fourth byte should be the same number.