Copy a image on a new larger image - python

I have a color image sourceImage and I would copy this image on a new larger color image destImage: the source image should be centered over the new image. In order to perform this procedure, I wrote the following code:
destHeight: the height of the new larger image
destWidth: the width of the new larger image
sourceFilename: the path of the source image
sourceImage = cv2.imread(sourceFilename,1)
imgHeight, imgWidth, imgChannels = sourceImage.shape[:3]
#print sourceImage.shape[:3]
destImage = np.zeros((destHeight,destWidth,imgChannels), np.uint8)
#print destImage.shape[:3]
yBorder = (destHeight-imgHeight)/2
xBorder = (destWidth-imgWidth)/2
#print yBorder, xBorder
destImage[yBorder:imgHeight,xBorder:imgWidth] = sourceImage
cv2.imshow('dst', destImage)
cv2.waitKey(0)
But when I run the script, the python interpreter displays the following error:
Traceback (most recent call last):
File "examples.py", line 30, in <module>
destImage[yBorder:imgHeight,xBorder:imgWidth] = sourceImage
ValueError: shape mismatch: objects cannot be broadcast to a single shape
What is the reason for this error? How to solve it?

Try this:
destImage[yBorder:yBorder + imgHeight,xBorder:xBorder + imgWidth] = sourceImage
The slice syntax is start:stop, not start:width.

Related

How do I crop a video steam that's already been resized?

I'm using PILs ImageGrab function to capture an application window in real-time for image detection with OpenCV. I've managed to scale the captured window down to increase the speed of image detection. However, I'm getting a number of false positives I can't seem to avoid. I actually only need to capture a small section of the window 761 34 1142 68
while True:
# Grab PSS Window and find size
window = pygetwindow.getWindowsWithTitle('App')[0]
x1 = window.left
y1 = window.top
height = window.height
width = window.width
x2 = x1 + width
y2 = y1 + height
# Actual Video Loop, cropped down to the specific window,
# resized to 1/2 size, and converted to BGR for OpenCV
haystack_img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
(width, height) = (haystack_img.width // 2, haystack_img.height // 2)
haystack_img_resized = haystack_img.resize((width, height))
########### Line in Question ##############
haystack_img_cropped = haystack_img_resized[761: 34, 1142:68]
haystack_img_np = np.array(haystack_img_cropped)
haystack = cv.cvtColor(haystack_img_np, cv.COLOR_BGR2GRAY)
cv.imshow("Screen", haystack)
I tried using OpenCV to slice the image but I get the error:
C:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips>C:/Users/coyle/AppData/Local/Programs/Python/Python39/python.exe c:/Users/coyle/OneDrive/froggy-pirate-master/avoidShips/avoidShipActual/test7.py
Traceback (most recent call last):
File "c:\Users\test7.py", line 103, in <module>
objectDetection(ships_to_avoid, 0.92)
File "c:\Users\test7.py", line 61, in objectDetection
haystack_img_cropped = haystack_img_resized[761:34, 1142:68]
TypeError: 'Image' object is not subscriptable
And I tried the .crop method:
haystack_img_resized = haystack_img.resize((width, height))
haystack_img_resized.crop((761,34,1164,65))
haystack_img_np = np.array(haystack_img_resized)
which produces no error but hasn't actually cropped anything.
How do I crop my video stream?
haystack_img_cropped = np.array(haystack_img_resized)[761: 34, 1142:68] should work.
For your questions,
You have to convert PIL's Image to Numpy's array before slicing.
.crop() returns new modified PIL's Image instance rather than modifying the existing one. PIL's methods typically return a new Image instance.
Not sure why, but loading the cropped image into a variable and using that variable worked.
crop = haystack_img_resized.crop((761,34,1164,65))
haystack_img_np = np.array(crop)

Python Pillow Image.load() method has limitations?

I'm trying to do some image processing in python.
I'm using Pillow 8.4.0 for this purpose and I need to work on individual pixels (here I'm just trying to save pixels in a text file), therefore I'm trying to use Image.load() method and looping over it but it is throwing IndexError: image index out of range
Is there a limitation in Image.load() function that is preventing me to do this?
from PIL import Image
with Image.open('nature.jpg') as img:
print("Image size is : " ,img.size)
pixels = img.load()
with open('file.txt', 'w') as file:
for row in range(img.height):
for col in range(img.width):
file.write(str(pixels[row, col])+ ' ')
file.write('\n')
Output is:
Image size is : (1024, 768)
Traceback (most recent call last):
File "main.py", line 13, in <module>
file.write(str(pixels[row, col])+ ' ')
IndexError: image index out of range
Pillow expects (x,y) rather than (y,x). Please try following:
from PIL import Image
img = Image.open('nature.jpg')
pixels = img.load()
print(pixels[img.width-1,img.height-1]) # does provide tuple describing pixel
print(pixels[img.height-1,img.width-1]) # IndexError for non-square image

Unable to broadcast an image on another image using python

cropped_image_resized = cropped_image.resize((400, 100),
Image.ANTIALIAS)
imshow(cropped_image_resized)
height = np.size(cropped_image, 0)
width = np.size(cropped_image, 1)
print(cropped_image.size)
print(height, width)
background_image = np.zeros([100,400,3],dtype=np.uint8)
imshow(background_image)
background_image[0:26,0:43] = cropped_image_resized
imshow(background_image)
ValueError Traceback (most recent call last)
<ipython-input-155-061e7c389661> in <module>
----> 1 background_image[0:26,0:43] = cropped_image_resized
2 imshow(background_image)
ValueError: could not broadcast input array from shape (100,400,3) into shape (26,43,3)```
You’re trying to take an image that is 400x100 and shoving it in a space of 26x43.
You either need to resize the cropped image to 26x43 (or smaller) or you need to change the dimensions of background_image that you’re trying to shove the cropped image into. For example:
cropped_image_resized = cropped_image.resize((26, 43), Image.ANTIALIAS)
background_image[0:26,0:43] = cropped_image_resized
Or this could work (I can’t check, but I believe it should?):
background_image = np.zeros([150,450,3],dtype=np.uint8)
background_image[:,:] = cropped_image_resized
Incidentally, the background image won’t be a background image anymore if you leave it as:
background_image = np.zeros([100,400,3],dtype=np.uint8)
As the original cropped image (400x100) will take up all available pixel values.

Image module (from PIL) not recognizing mode = "HSV"

I'm trying to take my HSV values and make an image out of it. Here is my code:
from __future__ import division
from PIL import Image
import numpy as np
import colorsys
fp = open('pixels.txt', 'w')
fp2 = open('hsv.txt', 'w')
im = Image.open('colorimage.png')
imrgb = im.convert("RGB")
scale = 255.0
pixels = list(imrgb.getdata())
width, height = im.size
pixels = [pixels[i * width:(i + 1) * width] for i in xrange(height)]
for pixel in pixels:
for x in pixel:
print>>fp, x
x = [x[0]/255,x[1]/255,x[2]/255]
y = colorsys.rgb_to_hsv(*x)
w = [y[0]*360, y[1]*100, y[2]*100]
h,s,v = [y[0]*360, y[1]*100, y[2]*100]
print>>fp2, w
newimg = Image.new("HSV", im.size)
print "done"
The Image.new says it takes modes: http://pillow.readthedocs.io/en/4.0.x/handbook/concepts.html#concept-modes
But it doesn't read "HSV" as a mode. It says this as the error:
Traceback (most recent call last):
File "RGBtoHIS.py", line 25, in <module>
newimg = Image.new("HSV", im.size)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PIL-1.1.7-py2.7-macosx-10.6-x86_64.egg/PIL/Image.py", line 1763, in new
return Image()._new(core.fill(mode, size, color))
ValueError: unrecognized mode
Has anyone else had this issue with the Image module?
Other:
I would like to create a Hue image and a Saturation image. Is there a way to do this with the hue and saturation values I have?
You're referencing the Pillow docs, but you're not using Pillow -- you're using the original PIL version 1.1.7, as shown by your error message:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/
site-packages/PIL-1.1.7-py2.7-macosx-10.6-x86_64.egg/PIL/Image.py", line 1763, in new
and according to its documentation, it doesn't support HSV as a mode (see here).
Uninstall PIL, install Pillow, and then you should be able to do
In [12]: PIL.__version__
Out[12]: '3.4.2'
In [13]: Image.new("HSV", (100,100))
Out[13]: <PIL.Image.Image image mode=HSV size=100x100 at 0x7F4FA00F4F60>

OpenCV Python copying certain portion of image to another

I want to calculate the difference betwwn two images. I'm only interested in the difference value for a certain portion of image. For that i am copying the required portion of image to a temp images, and operating on those images. However using the pixel allocation using as specified on http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_core/py_basic_ops/py_basic_ops.html. Here it is given,
ball = img[280:340, 330:390]
img[273:333, 100:160] = ball
Using the similar logic, i have written a python program,
import cv2
import numpy as np
img_file = 'carparking2_1.jpg'
img = cv2.imread(img_file, cv2.IMREAD_COLOR)
img_withoutcar = 'carparking2_1.jpg'
img_withcar = 'carparking2.jpg'
img1 = img_withoutcar[47:151, 106:157]
img2 = img_withcar[47:151, 106:157]
diff1 = cv2.absdiff(img1, img2)
diff2 = cv2.absdiff(img1, img1)
print 'RGB shape: ', img.shape # Rows, cols, channels
print 'Difference with car and without: ', diff1
print 'Difference with car and with car: ', diff2
However, im getting the output message:
File "D:/Projects/IoT Smart Parking/differenceinframes.py", line 8, in <module>
img1 = img_withoutcar[47:151, 106:157]
TypeError: string indices must be integers, not tuple
I am running Python 2.7 with OpenCV 3.1.0 on Windows 10.
You are getting the error because your command is trying to slice the string 'carparking2_1.jpg' as if it were the image data.
#First assign the file names:
file_name_without_car='carparking2_1.jpg'
file_name_with_car='carparking2.jpg'
#load the images
img_withoutcar= cv2.imread(file_name_without_car, cv2.IMREAD_COLOR)
img_withcar= cv2.imread(file_name_with_car, cv2.IMREAD_COLOR)
#now you can slice regions of the images
#note that color images have a third dimension for color channel.
img1 = img_withoutcar[47:151, 106:157,:]
img2 = img_withcar[47:151, 106:157,:]

Categories