OpenCV .imshow() is not displaying a properly sized image - python

I am trying to read an image using opencv, do some transformations (resize and offsets), then as a last step, do a crop on the image. In my final line crop_img = offset_image[0:1080, 0:1920].copy(), I expect a cropped 1920x1080 image to be created. My crop_img.size print out shows that that is correct. But, when I do an .imshow(), it is displaying the full sized, original image.
import numpy as np
import cv2 as cv
import copy
original = cv.imread("IMG_0015_guides.jpg", cv.IMREAD_UNCHANGED)
img_resize = cv.resize(original, (0,0), fx=.9, fy=.9)
rows,cols,_ = img_resize.shape
M = np.float32([[1,0,100],[0,1,50]])
offset_image = cv.warpAffine(img_resize,M,(cols,rows))
crop_img = offset_image[0:1080, 0:1920].copy()
print('img_resize {}'.format(img_resize.shape))
print('offset_image {}'.format(offset_image.shape))
print('cropped {}'.format(crop_img.shape))
cv.imshow('image',crop_img)
cv.waitKey(0)
cv.destroyAllWindows()
>>> img_resize (3110, 4666, 3)
>>> offset_image (3110, 4666, 3)
>>> cropped (1080, 1920, 3)
I'm totally baffled. Why is it not showing me the cropped 1920x1080 image?

Working with massive images can get confusing when visualizing with OpenCV's imshow.
I ran your code and it seems like its doing what you expect it to do. I suggest resizing your image again for visualization purposes only. The following code ran successfully on this image.
import numpy as np
import cv2 as cv
import copy
original = cv.imread("4k-image-tiger-jumping.jpg", cv.IMREAD_UNCHANGED)
# resize original for visualization purposes only
print('original {}'.format(original.shape))
original_resized = cv.resize(original, (0,0), fx=.1, fy=.1)
cv.imshow('original_resize',original_resized)
img_resize = cv.resize(original, (0,0), fx=.9, fy=.9)
rows,cols,_ = img_resize.shape
M = np.float32([[1,0,100],[0,1,50]])
offset_image = cv.warpAffine(img_resize,M,(cols,rows))
crop_img = offset_image[0:1080, 0:1920].copy()
print('img_resize {}'.format(img_resize.shape))
print('offset_image {}'.format(offset_image.shape))
print('cropped {}'.format(crop_img.shape))
# resize cropped for visualization purposes only
vis_r,vis_c,_ = original_resized.shape
cropped_resized = cv.resize(crop_img, (vis_c, vis_r))
cv.imshow('cropped_resized',cropped_resized)
# cv.imshow('image',crop_img)
cv.waitKey(0)
cv.destroyAllWindows()

Related

RGB to grayscale without cmaps

is there a way to change an image to grayscale without using cmap in matpotlib?
my function is
def grayscale(image):
img = image.copy()
r=img[:,:,0]*0.3
g=img[:,:,1]*0.59
b=img[:,:,2]*0.11
gray=r+g+b
img=np.dstack((gray,gray,gray))
return img
plt.imshow(img)
However, the image I got is just black and white, not in grayscale TT. Then when I tried using gray=r+g+b,plt.imshow(img), I got a green and yellow picture. I have tried searching everywhere to get clues and all I found was the use of cmaps. However the project I am doing doesn't allow us to use cmap.
Here is a working solution using your code - you should add your picture path in the image_path variable:
import numpy as np
from PIL import Image
import cv2
def grayscale(image):
img = np.asarray(Image.open(image))
r = img[:,:,0]*0.3
g = img[:,:,1]*0.59
b = img[:,:,2]*0.11
gray = r+g+b
return gray
image_path = "test.jpg"
img = grayscale(image_path)
cv2.imwrite('greyscale.jpg',img)
The trick was that you did not load the image in a proper way.

CVLIB - how to add blurred subface to the original image?

Friends, I need to implement a code, which blur faces from given images (I am not a dev so this is really difficult to me). I found out that I can use OpenCV and cvlib to do that and found a sample code (repository from cvlib) which does part of the job.
I understood that I need to get the subfaces and apply the face blur to them and I could do it but now I don't know how to add the blurred face to original image. Could someone help me with that?
import cvlib as cv
import sys
from cv2 import cv2
import os
# read input image
image = cv2.imread('path')
# apply face detection
faces, confidences = cv.detect_face(image)
print(faces)
print(confidences)
# loop through detected faces
for face,conf in zip(faces,confidences):
(startX,startY) = face[0],face[1]
(endX,endY) = face[2],face[3]
subFace = image[startY:endY,startX:endX]
subFace = cv2.GaussianBlur(subFace,(23, 23), 30)
# display output
# press any key to close window
cv2.imshow("face_detection", image)
cv2.waitKey()
cv2.imshow("face_detection", subFace)
# release resources
cv2.destroyAllWindows()
I finally figured out how to do it:
import cvlib as cv
import sys
from cv2 import cv2
import os
# read input image
image = cv2.imread('path')
# apply face detection
faces, confidences = cv.detect_face(image)
# print the array with the coordinates and the confidence
print(faces)
print(confidences)
# loop through detected faces
for face,conf in zip(faces,confidences):
(startX,startY) = face[0],face[1]
(endX,endY) = face[2],face[3]
# get the subface
subFace = image[startY:endY,startX:endX]
# apply gaussian blur over subfaces
subFace = cv2.GaussianBlur(subFace,(23, 23), 30)
# add the subfaces to de original image
image[startY:startY+subFace.shape[0], startX:startX+subFace.shape[1]] = subFace
cv2.imshow("face_detection", image)
cv2.waitKey()
# save output
cv2.imwrite("face_detection.jpg", image)
# release resources
cv2.destroyAllWindows()

How to resize output images in python?

Hi i run this blurdetection code in python ( source : https://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/ )
# import the necessary packages
from imutils import paths
import argparse
import cv2
def variance_of_laplacian(image):
# compute the Laplacian of the image and then return the focus
# measure, which is simply the variance of the Laplacian
return cv2.Laplacian(image, cv2.CV_64F).var()
# loop over the input images
for imagePath in paths.list_images("images/"):
# load the image, convert it to grayscale, and compute the
# focus measure of the image using the Variance of Laplacian
# method
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
fm = variance_of_laplacian(gray)
text = "Not Blurry"
# if the focus measure is less than the supplied threshold,
# then the image should be considered "blurry"
if fm < 100:
text = "Blurry"
# show the image
cv2.putText(image, "{}: {:.2f}".format(text, fm), (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3)
cv2.imshow("Image", image)
print("{}: {:.2f}".format(text, fm))
key = cv2.waitKey(0)
with this 2173 x 3161 input file
input image
and this is the output show
the output image
The image is zoom in and dont shown full.
In the source code, they use 450 x 600 px input image :
input in source code
and this is the output :
output in source code
I think the pixels of the image influences of the output. So, how can i get the output like the output in source code to all image?
do i have to resize the input image? How to? but if I do it I'm afraid it will affect the result of his blur
Excerpt from the DOCUMENTATION.
There is a special case where you can already create a window and load image to it later. In that case, you can specify whether window is resizable or not. It is done with the function cv2.namedWindow(). By default, the flag is cv2.WINDOW_AUTOSIZE. But if you specify flag to be cv2.WINDOW_NORMAL, you can resize window. It will be helpful when image is too large in dimension and adding track bar to windows.
I just used the code placed in the question but added line cv2.namedWindow("Image", cv2.WINDOW_NORMAL) as mentioned in the comments.
# import the necessary packages
from imutils import paths
import argparse
import cv2
def variance_of_laplacian(image):
# compute the Laplacian of the image and then return the focus
# measure, which is simply the variance of the Laplacian
return cv2.Laplacian(image, cv2.CV_64F).var()
# loop over the input images
for imagePath in paths.list_images("images/"):
# load the image, convert it to grayscale, and compute the
# focus measure of the image using the Variance of Laplacian
# method
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
fm = variance_of_laplacian(gray)
text = "Not Blurry"
# if the focus measure is less than the supplied threshold,
# then the image should be considered "blurry"
if fm < 100:
text = "Blurry"
# show the image
cv2.putText(image, "{}: {:.2f}".format(text, fm), (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3)
cv2.namedWindow("Image", cv2.WINDOW_NORMAL) #---- Added THIS line
cv2.imshow("Image", image)
print("{}: {:.2f}".format(text, fm))
key = cv2.waitKey(0)
In case you want to use the exact same resolution as the example you've given, you can just use the cv2.resize() https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#resize method or (in case you want to keep the ratio of the x/y coordinates) use the imutils class provided in https://www.pyimagesearch.com/2015/02/02/just-open-sourced-personal-imutils-package-series-opencv-convenience-functions/
You still have to decide if you want to do the resizing first. It shouldn't matter in which order you greyscale or resize.
Command you can add:
resized_image = cv2.resize(image, (450, 600))

greyscale image normalization issue with MINMAX

I am trying to normalize a bunch of images which I have scaled to 32x32 pixel size. I was initially wanting to use x-median/std for normalization, but I found some code to use MINMAX instead so I am trying that. I need to get the image into the 0 to 1 range, so I assume that dtype 32F would do that, so I think this is where the problem lies. When I run the code, the normalized image is completely black. Any advice on how to solve that?
Here is the code:
import cv2
import numpy as np
from PIL import Image
image = cv2.imread("image.png", cv2.IMREAD_UNCHANGED) # uint8 image
norm_image = np.zeros((32, 32))
norm_image = cv2.normalize(image, norm_image, alpha=0, beta=1, norm_type = cv2.NORM_MINMAX, dtype=cv2.CV_32F)
im = Image.fromarray(norm_image)
if im != 'RGB':
im = im.convert('RGB')
im.save("image_norm.png")
cv2.waitKey(0)
cv2.destroyAllWindows()
Sample image

OpenCV Python: Normalize image

I'm new to OpenCV. I want to do some preprocessing related to normalization. I want to normalize my image to a certain size. The result of the following code gives me a black image. Can someone point me to what exactly am I doing wrong? The image I am inputting is a black/white image
import cv2 as cv
import numpy as np
img = cv.imread(path)
normalizedImg = np.zeros((800, 800))
cv.normalize(img, normalizedImg, 0, 255, cv.NORM_MINMAX)
cv.imshow('dst_rt', self.normalizedImg)
cv.waitKey(0)
cv.destroyAllWindows()
as one can see at: http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#cv2.normalize, there is a → dst that say that the result of the normalize function is returned as output parameter. The function doesn't change the input parameter dst in-place.
(The self. in cv.imshow('dst_rt', self.normalizedImg) line is a typo)
import cv2 as cv
import numpy as np
path = r"C:\Users\Public\Pictures\Sample Pictures\Hydrangeas.jpg"
img = cv.imread(path)
normalizedImg = np.zeros((800, 800))
normalizedImg = cv.normalize(img, normalizedImg, 0, 255, cv.NORM_MINMAX)
cv.imshow('dst_rt', normalizedImg)
cv.waitKey(0)
cv.destroyAllWindows()
It's giving you a black image because you are probably using different sizes in img and normalizedImg.
import cv2 as cv
img = cv.imread(path)
img = cv.resize(img, (800, 800))
cv.normalize(img, img, 0, 255, cv.NORM_MINMAX)
cv.imshow('dst_rt', img)
cv.waitKey(0)
cv.destroyAllWindows()
Update: In NumPy there are more intuitive ways to do this ref:
a = np.random.rand(3,2)
# Normalised [0,1]
b = (a - np.min(a))/np.ptp(a)
# Normalised [0,255] as integer: don't forget the parenthesis before astype(int)
c = (255*(a - np.min(a))/np.ptp(a)).astype(int)
# Normalised [-1,1]
d = 2.*(a - np.min(a))/np.ptp(a)-1
When you call cv.imshow() you use self.normalizedImg, instead of normalizedImg.
The self. is used to identify class members and its use in the code you've written is not appropriate. It shouldn't even run as written. However I assume this code has been extracted from a class definition, but you must be consistent in naming variables and self.normalizedImg is different from normalizedImg.

Categories

Resources