OpenCV and rawkit python - python

I load a cr2 file in argv... then I want to convert it to an opencv format so i can use it in the app (not save it as a file). It is loaded first with Rawkit.
raw_image = Raw(sys.argv[1])
buffered_image = np.array(raw_image.to_buffer())
image = Image.frombytes('RGB', (raw_image.metadata.width, raw_image.metadata.height), buffered_image)
image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
That is my attempt.
The image loads and looks very poor with a bunch of diagonal zigzags
In essence :I need to convert
image = Image.frombytes('RGB', (raw_image.metadata.width, raw_image.metadata.height), buffered_image)
to the same format as what it would be if i used
image = cv2.imread(imagePath)

It may be easier if you use rawpy:
import rawpy
import cv2
raw = rawpy.imread("path/to/file") # access to the RAW image
rgb = raw.postprocess() # a numpy RGB array
image = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR) # the OpenCV image
cv2.imwrite("foo.png", image)
I just tried it and it worked without a problem.

Related

When PIL is converting an RBG image in the form of a numpy array to a png it delivers an odd result

I am trying to convert this .tif file to a .png, here is the image (I attached a link because it is 250mb): https://drive.google.com/file/d/1nEvG8O5NM1bsKM-fSo66QJF7mZyR_fh-/view?usp=sharing
Here is my current code, it returns an grayscale image with multiple copies of the original .tif in one .png, it is suppose to return an RGB image:
import rasterio
import numpy as np
from PIL import Image
dataset = rasterio.open("world.tif")
window = rasterio.windows.Window(0, 0, 21600, 10800)
out = dataset.read(window=window)
out = out.reshape(10800, 21600, 3).astype(np.uint8)
img = Image.fromarray(out, "RGB")
img.save("out.png")
I'm not sure why you are mixing up PIL/Pillow and raster like that. You can just do the following with PIL:
from PIL import Image
# Allow monster large images
Image.MAX_IMAGE_PIXELS = None
# Load image
im = Image.open('world.tif')
# Reduce to manageable size and save as PNG
small = im.resize((2160,1080))
small.save('result.png')

PIL Image.save() convert doesn't maintain RGB color

I am trying to save a numpy array as RGB image using PIL.Image.save(),but it the saved image is not RGB. How do I save the image as RGB ? I am receiving the image as numpy array.
image_with_detections = np.array(image_with_detections)
image = Image.fromarray(image_with_detections.astype('uint8'), 'RGB')
image.save(save_path)
The link to original image
The link to image saved by Image.save()
You can do something like the following
image_with_detections = np.array(image_with_detections)
image = Image.fromarray(image_with_detections.astype('uint8'), 'RGB')
image = image[:,:,::-1]
image.save(save_path)

Open/ read rw2 image with color using python?

Can someone open this raw file with color? It is an image and I tried everything with numpy, rawpy, fastrawviewer etc. It is almost 3 days I try to open with color but I failed.
import numpy as np
import cv2
fd = open('img.rw2', 'rb')
ROWS = 2000
COLS = 2000
f = np.fromfile(fd, dtype=np.uint8,count=ROWS*COLS*4)
im = f.reshape((ROWS, COLS,4))
fd.close()
cv2.imshow('img.rw2', im)
cv2.waitKey()
cv2.destroyAllWindows()
If your image was 2000x2000 RGB it would be 12,000,000 bytes, but it is 16,000,000. So try reading it as RGBA, rather than RGB.
im = np.fromfile('img.raw', dtype=np.uint8).reshape((2000,2000,4))
[![enter image description here][1]][1]
If the image was saved as RGBA, you will need to correct the ordering in OpenCV because that will use BGRA - use cv2.cvtColor().

I can't change my RGB colour into grayscale images in python using CV

So, I am doing this project to detect diabetic retinopathy using deep learning. I however am stuck in the preprocessing image section as the pictures that are in different folders(for diff stages of DR) wouldn't convert into grayscale nomatter how much I try.
Here is my functions that does the early preprocessing stage:
def preprocessing(conditionname,directory):
for image in os.listdir(directory):
label = eye_label(conditionname,image)
path = os.path.join(directory,image)
image = cv2.imread(path,cv2.IMREAD_COLOR) #Reading the colour images
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #Changing coloured image into black and white
#image = cv2.addWeighted(image,10,cv2.GaussianBlur(image , (0,0) , sigma_x) ,-4 ,12)
image = cv2.resize(image,(image_size,image_size)) #Changing the size of each image
return image
Try using your debugger or IDE to check everything gives you the result you expect, one step at a time.
If you load an image, print its shape:
img = cv2.imread(...)
print(image.shape)
If you convert an image to greyscale, check it has 1 channel afterwards:
img = cv2.cvtColor(...)
print(image.shape)
If you resize an image, check its size is what you expect:
img = cv2.resize(...)
print(image.shape)
If you are going to return an image from a function, check its size and type:
print(result.shape, result.dtype)
return result

OpenCV return None whan imread is called with GDAL support

I have a very simple program in python with OpenCV and GDAL. In this program i read GeoTiff image with the following line
image = cv2.imread(sys.argv[1], cv2.IMREAD_LOAD_GDAL | cv2.IMREAD_COLOR)
The problem is for a specific image imread return None. I am using images from: https://www.sensefly.com/drones/example-datasets.html
Image in Assessing crops with RGB imagery (eBee SQ) > Map (orthomosaic) works well. Its size is: 19428, 19784 with 4 bands.
Image in Urban mapping (eBee Plus/senseFly S.O.D.A.) > Map (orthomosaic) doesn't work. Its size is: 26747, 25388 and 4 bands.
Any help to figure out what is the problem?
Edit: I tried the solution suggested by #en_lorithai and it works, the problem is then I need to do some image processing with OpenCV and the image loaded by GDAL has several issues
GDAL load images as RGB instead of BGR (used by default in OpenCV)
The image shape expected by OpenCV is (width, height, channels) and GDAL return an image with (channels, width, height) shape
The image returned by GDAL is flipped in Y-axe and rotate clockwise by 90 degree.
The image loaded by OpenCV is (resized to 700x700):
The image loaded by GDAL (after change shape, of course) is (resized to 700x700)
Finally, If I try to convert this image from BGR to RGB with
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
I get (resized to 700x700)
I can convert from GDAL format to OpenCV format with the following code
image = ds.ReadAsArray() #Load image with GDAL
tmp = image.copy()
image[0] = tmp[2,:,:] # swap read channel and blue channel
image[2] = tmp[0,:,:]
image = np.swapaxes(image,2,0) # convert from (height, width, channels) to (channels, height, width)
image = cv2.flip(image,0) # flip in Y-axis
image = cv2.transpose(image) # Rotate by 90 degress (clockwise)
image = cv2.flip(image,1)
The problem is I think that this is a very slow process and I want to know if there is a automatic convert-process.
You can try and open the image in gdal instead
from osgeo import gdal
g_image = gdal.Open('161104_hq_transparent_mosaic_group1.tif')
a_image = g_image.ReadAsArray()
can't test as i don't have enough available memory to open that image.
Edit: equivalent operation on another image
from osgeo import gdal
import matplotlib.pyplot as plt
g_image = gdal.Open('Water-scenes-014.jpg') # 3 channel rgb image
a_image = g_image.ReadAsArray()
s_image = np.dstack((a_image[0],a_image[1],a_image[2]))
plt.imshow(s_image) # show image in matplotlib (no need for color swap)
s_image = cv2.cvtColor(s_image,cv2.COLOR_RGB2BGR) # colorswap for cv
cv2.imshow('name',s_image)
Another method of getting individual bands from gdal
g_image = gdal.Open('image_name.PNG')
band1 = g_image.GetRasterBand(1).ReadAsArray()
You can then do a numpy dstack of each of the bands.

Categories

Resources