cv2.imshow command doesn't work propley . Shows incomplete image - python

I am able to open the image but my image is not completely visible in the window . I mean it shows me cropped version of the image im using. It would be great if you can help me visualize the complete image shown through cv2.imshow().I am using the visual studio and below is the code:
import numpy as np
import cv2
Org_img=cv2.imread('coins.png',1)
img=cv2.imread('coins.png',0)
cv2.imshow('image',img)
cv2.imshow('image2',Org_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

The image is probably larger than the screen, use the resize function to adjust for the desired output, also take a look on the shape for checking these values and window flags in the second link.
import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=factor, fy=factor, interpolation = cv.INTER_CUBIC)
If factor > 1.0 the image is getting larger than the original and if factor < 1.0 you are reducing the image (factor = 0.5 will divide by 2), fx and fy can be different values.
See geometric transformations
Window flags

Related

How to read a RAW image file format into OpenCV without any loss of resolution?

I am trying to import a Nikon '.NEF' file into OpenCV. '.NEF' is the file extension for a RAW file format for pictures captured by Nikon cameras. When I open the file in Preview on a Mac, I see that the resolution is 6000 by 4000, and the picture is extremely clear. However, when I import it into OpenCV, I see only 120 by 160 (by 3 for RGB channels) data points, and this leads to a big loss in resolution.
My understanding is that there are 120 by 160 pixels in the NumPy array storing the information about pixels for OpenCV. I tried using -1 for the IMREAD_UNCHANGED flag, but many pixels were left out and image quality was greatly affected.
For your reference, here is my code:
# first Jupyter block
img = cv2.imread('DSC_1051.NEF', -1)
img.shape
Performing img.shape returns (120, 160, 3).
# second Jupyter block
cv2.namedWindow("Resize", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Resize", 1000, 700)
# Displaying the image
cv2.imshow("Resize", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Summary of problem:
Original image shape is (6000, 4000)
Open CV imports (120, 160), leading to a big loss in resolution
Using the IMREAD_UNCHANGED flag did not lead to OpenCV importing all the pixels in the image, leading to a loss in quality of the image upon performing cv2.imshow().
My question: how can I use OpenCV to import the desired number of pixels? Is there a specific function that I can use? Am I missing an argument to be passed?
If you want to manipulate RAW images without losing resolution with python you'd need to check on a specialized library like rawpy
import rawpy
with rawpy.imread('filename.NEF') as raw:
raw_image = raw.raw_image
You can check the rawpy documentation for more information
Notes:
To install rawpy, Python<=3.7 is required
If you explain a little bit more what do u need to do with the image I could help you with that
Example 1: how to save .NEF as .jpg
Option A: rawpy + Pillow (you need to install Pillow too)
import rawpy
from PIL import Image
with rawpy.imread('filename.NEF') as raw:
rgb = raw.postprocess(use_camera_wb=True)
Image.fromarray(rgb).save('image.jpg', quality=90, optimize=True)
Option B: rawpy + cv2
import rawpy
import cv2
with rawpy.imread('filename.NEF') as raw:
rgb = raw.postprocess(use_camera_wb=True)
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
cv2.imwrite("image.jpg",bgr)
Quality comparison
I test the code with this 19.2mb .NEF image and I got these results:
Method
.jpg output size
Dimensions
PIL
9kb
320x212
cv2
14kb
320x212
rawpy + PIL
1.4mb
4284 × 2844
rawpy + cv2
2.5mb
4284 × 2844
Example 2: show .NEF with cv2
import rawpy
import cv2
with rawpy.imread('filename.NEF') as raw:
rgb = raw.postprocess(use_camera_wb=True)
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
cv2.imshow('image', bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

Subtract 16 bit tiff image in python

I have two 16 bit tiff image, of which one is a background and I have to remove it from all the image. I use the following code, however I get the error saying
return image1._new(image1.im.chop_difference(image2.im))
ValueError: image has wrong mode
from PIL import Image, ImageChops
im1 = Image.open("main.tif")
im2 = Image.open("background.tif")
diff = ImageChops.difference(im2, im1)
diff.show()
when I check the mode using print(im1.mode) I get
I,16
I do not understand this error. Also, I don't know if Pillow is able to subtract 16 bit tiff images or not. I need help to resolve this error and get a subtracted image.
The two images are
main: main image
background image: background
I think I would do it like this:
#!/usr/bin/env python3
from PIL import Image
import numpy as np
# Open both images and make into Numpy arrays of signed 32-bit integers
main = np.array(Image.open('main.tif')).astype('int32')
back = np.array(Image.open('background.tif')).astype('int32')
# Calculate difference with saturation
diff = np.clip(main - back, 0, main.max())
# Revert to PIL Image and save
Image.fromarray(diff.astype(np.uint16)).save('result.tif')
If you stretch the contrast, you get:

Changing image size while capturing using webcam using imageio

I am trying to capture image with each function call
import imageio as iio
camera = iio.get_reader("<video0>")
screenshot = camera.get_data(0)
plt.imsave(filename, screenshot)
camera.close()
I am able to save the image but the image size is varying sometime it is of the size of 960540 and sometime 1280720.
I went through the documentation of imageio but did not find any attribute to set its shape. I want a fix shape of image all the time.
I have tried OpenCV, it has its own limitation w.r.t my requirements.
So please suggest something in this package only.
Could anyone please help.
Your comment made clear you want to keep the resolution consistent for the duration of the whole video. As imageio does not provide a resize operation I suggest you to use skimage to handle that part.
import imageio as iio
import matplotlib.pyplot as plt
from skimage.transform import resize
camera = iio.get_reader("<video0>")
filename = "experiment_"
# randomly set to 30 frames for this example
for i in range(0, 30):
screenshot = camera.get_data(i)
# skimage resize function here
screenshot = resize(screenshot, (1280, 720))
final_filename = str(i) + ".jpg"
plt.imsave(filename+final_filename, screenshot)
camera.close()

Expanding a contour in python cv2

Using cv2, I am able to find the contours of text in an image. I would like to remove said text and replace it with the average pixel of the surrounding area.
However, the contours are just a bit smaller than I would like, resulting in a blurred edge where one can barely tell what the original text was:
I once chanced upon a cv2 tutorial with a stylized "j" as the sample image. It showed how to "expand" a contour in a manner similar to adding a positive sample next to every pre-existing positive sample in a mask.
If such a method does not already exist in cv2, how may I do this manually?
The function I sought was dilation, as detailed here:
https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html
import cv2
import numpy as np
img = cv2.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(img,kernel,iterations = 1)

Creating an RGB picture in Python with OpenCV from a randomized array

I want to create a RGB image made from a random array of pixel values in Python with OpenCV/Numpy setup.
I'm able to create a Gray image - which looks amazingly live; with this code:
import numpy as np
import cv2
pic_array=np.random.randint(255, size=(900,800))
pic_array_8bit=slika_array.astype(np.uint8)
pic_g=cv2.imwrite("pic-from-random-array.png", pic_array_8bit)
But I want to make it in color as well. I've tried converting with cv2.cvtColor() but it couldnt work.
The issue might be in an array definition or a missed step. Couldn't find a similar situation... Any help how to make a random RGB image in color, would be great.
thanks!
RGB image is composed of three grayscale images. You can make three grayscale images like
rgb = np.random.randint(255, size=(900,800,3),dtype=np.uint8)
cv2.imshow('RGB',rgb)
cv2.waitKey(0)
First, you should define a random image data consisting of 3 channels using numpy as shown below-
import numpy as np
data = np.random.randint(0, 255, size=(900, 800, 3), dtype=np.uint8)
Now use, python imaging library as shown below-
from PIL import Image
img = Image.fromarray(data, 'RGB')
img.show()
You can also save the image easily using save function
img.save('image.png')

Categories

Resources