How to convert wand image object to open cv image (numpy array) - python-2.7

I have imported wand using the following code
from wand.image import Image as WandImage
from wand.color import Color
with WandImage(filename=source_file, resolution=(RESOLUTION,RESOLUTION)) as img:
img.background_color = Color('white')
img.format = 'tif'
img.alpha_channel = False
How can i convert img object to open cv (cv2) image object in python?

You would simply write to a byte-array buffer, and pass to cv2.imdecode.
from wand.image import Image as WandImage
from wand.color import Color
import numpy
import cv2
RESOLUTION=72
source_file='rose:'
img_buffer=None
with WandImage(filename=source_file, resolution=(RESOLUTION,RESOLUTION)) as img:
img.background_color = Color('white')
img.format = 'tif'
img.alpha_channel = False
# Fill image buffer with numpy array from blob
img_buffer=numpy.asarray(bytearray(img.make_blob()), dtype=numpy.uint8)
if img_buffer is not None:
retval = cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)

Related

How to convert Django uploadedfile.InMemory into numpy array or Image

#Views.py-- I want to convert uploaded image file into numpy array(cv2.imread)
def upload(request):
if request.method == 'POST' and request.FILES['image_file']:
f = request.FILES['image_file']
myfile = str(f.read())
array_np = cv2.imread(myfile)
You can convert the byte into int and decode it using cv2.imdecode. Then you will get a cv2 image array.
image = cv2.imdecode(numpy.frombuffer(myfile , numpy.uint8), cv2.IMREAD_UNCHANGED)

What's wrong with the following code implementing knn?

This is the modified code from what I found here.
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Now we split the image to 5000 cells, each 20x20 size
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]
# Make it into a Numpy array. It size will be (50,100,20,20)
x = np.array(cells)
# Now we prepare train_data.
train = x[:,:50].reshape(-1,400).astype(np.float32) # Size = (2500,400)
img = cv2.imread('1.png')
img1 = cv2.imread('2.png')
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img = cv2.resize(img, (20,20)).astype(np.float32)
img1 = cv2.resize(img1, (20,20)).astype(np.float32)
img = img.flatten()
img1 = img1.flatten()
arr = [img,img1]
arr = np.asarray(arr)
# Create labels for train and test data
k = np.arange(10)
train_labels = np.repeat(k,250)[:,np.newaxis]
# Initiate kNN, train the data, then test it with test data for k=1
knn = cv2.ml.KNearest_create()
knn.train(train, 0,train_labels)
ret, result, neighbours, dist = knn.findNearest(arr, k=5)
for i in result:
print i
# save the data
np.savez('knn_data.npz',train=train, train_labels=train_labels)
# Now load the data
with np.load('knn_data.npz') as data:
print data.files
train = data['train']
train_labels = data['train_labels']
which works perfectly. But I can't figure out, how to use this knn_data.npz file.
This was my attempt:
import numpy as np
import cv2
from matplotlib import pyplot as plt
with np.load('knn_data.npz') as data:
print data.files
train = data['train']
train_labels = data['train_labels']
img = cv2.imread('1.png')
img1 = cv2.imread('2.png')
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
img = cv2.resize(img, (20,20)).astype(np.float32)
img1 = cv2.resize(img1, (20,20)).astype(np.float32)
img = img.flatten()
img1 = img1.flatten()
arr = [img,img1]
arr = np.asarray(arr)
knn = cv2.ml.KNearest_create()
ret, result, neighbours, dist = knn.findNearest(arr, k=5)
for i in result:
print i
The error message I got, which I could not fix was:
OpenCV Error: Assertion failed (test_samples.type() == 5 && test_samples.cols == samples.cols) in findNearest, file /io/opencv/modules/ml/src/knearest.cpp, line 325
Traceback (most recent call last):
File "knn1.py", line 20, in
ret, result, neighbours, dist = knn.findNearest(img, k=5)
cv2.error: /io/opencv/modules/ml/src/knearest.cpp:325: error: (-215) test_samples.type() == 5 && test_samples.cols == samples.cols in function findNearest
I am using opencv 3.2.0 on python 2.7.15 in ubuntu 18.04. The files 1.png and 2.png are RGB-image files.
In your example, you create the variables train and train_labels but never use them.
Add the following anywhere before you call knn.findNearest(arr, k=5):
train = data['train']
train_labels = data['train_labels']
knn = cv2.ml.KNearest_create()
knn.train(train, 0,train_labels)

convert pil gif image to pygame surface without saving it on the disk

I would like to get images from server side and display them on client side by pygame and not save each frame on disk. images are transferred using base64 encode and decode. when data is received from the other side it is decoded to PIL image. Then i can successfully save it to a temporary file ,open it with pygame and display it. however I would like to do it directly using image.tostring() but noting is displayed I am also noticed that when i save to temporary file pictures attributes are:
Surface(32x32x32 SW)
and when I do it directly:
Surface(32x32x8 SW)
thanks:
import base64
from io import BytesIO
import pygame
from PIL import Image
def gif__to_string(filePath):
gif_file = filePath
content = base64.encodestring(open(gif_file, 'rb').read())
return content
def string_to_gif(imageStr):
gif_image = Image.open(BytesIO(base64.b64decode(imageStr)))
return gif_image
def show_gif_working(im):
black = (0, 0, 0)
white = (255, 255, 255)
pygame.init()
width = 350;
height = 400
imageX = 200; # x coordnate of image
imageY = 30; #
screen = pygame.display.set_mode((width, height))
screen.fill(black)
im.save('temp.gif')
surface = pygame.image.load("temp.gif").convert()
screen.blit(surface, (imageY, imageY))
pygame.display.flip()
def show_gif_not_working(im):
black = (0, 0, 0)
white = (255, 255, 255)
pygame.init()
width = 350;
height = 400
imageX = 200; # x coordnate of image
imageY = 30; #
screen = pygame.display.set_mode((width, height))
screen.fill(black)
mode = im.mode
size = im.size
data = im.tostring()
surface1 = pygame.image.fromstring(data, size, mode)
screen.blit(surface1, (imageX, imageY))
pygame.display.flip()
def main():
content = gif__to_string('face5.gif')
print content
myImage = string_to_gif(content)
# show_gif_working(myImage)
show_gif_not_working(myImage)
main()
Have you tried using pygame.image.load[1] with a file-like object instead of a string?
You could pass a StringIO[2] object instead of a file.
I have the same problem!
The code from the top of this thread works with jpg-files, but now with gif's.
The simple idea with:
myimage = Image.open("test.gif")
pyimage = pygame.image.load(myimage)
puts out an error:
Traceback (most recent call last):
File "example.py", line 12, in <module>
pyimage = pygame.image.load(myimage)
TypeError: not a file object
I use Python 3.7 with the function:
pg.image.frombuffer(), or pg.image.fromstring()
The details:
import PIL.Image as Image
import pygame as pg
gif = Image.open('file.gif')
for i in range(gif.n_frames):
gif.seek(i)
surf = pg.image.frombuffer(gif.tobytes(), gif.size, gif.mode)
gif.seek(i) is to locate the gif to a unique position,
and the surf the Surface object that you want.

Subtracting Background From Image using Opencv in Python

The following program displays 'foreground' completely black and not 'frame'. I also checked that all the values in 'frame' is equal to the values in 'foreground'.
They have same channels,data type etc.
I am using python 2.7.6 and OpenCV version 2.4.8
import cv2
import numpy as np
def subtractBackground(frame,background):
foreground = np.absolute(frame - background)
foreground = foreground >= 0
foreground = foreground.astype(int)
foreground = foreground * frame
cv2.imshow("foreground",foreground)
return foreground
def main():
cap = cv2.VideoCapture(0)
dump,background = cap.read()
while cap.isOpened():
dump,frame = cap.read()
frameCopy = subtractBackground(frame,background)
cv2.imshow('Live',frame)
k = cv2.waitKey(10)
if k == 32:
break
if __name__ == '__main__':
main()
Because you are telling OpenCV to display a 64bpc image. You cast .astype(int) which means 'int64' or 'int32' depending on your architecture. Cast .astype('uint8') instead. Your maximum brigthness of 255 looks black compared to the full 64bit range.
Related problem:
foreground = np.absolute(frame - background)
Integer underflow. The expression frame - background does not automatically convert to a signed data type. You need a different data type for such calculations (try float if performance doesn't matter), or find an OpenCV function that handles the whole thing for you.
foreground = foreground >= 0
Because foreground is of type 'uint8', which can never be negative, the result is all ones. Simply insert some print repr(foreground) statements to debug such problems.
You can use background sub tractor provided by opencv itself.
you can find the tutorial here.
for example look at the code
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
while(1):
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
cv2.imshow('frame',fgmask)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
replace foreground = np.absolute(frame - background)
with foreground = cv2.absdiff(frame, background)

Opencv using camera with matplotlib

I am trying to create a program that will show me different types of gradients of a video I am capturing. This is my code:
import cv2
import numpy as np
from matplotlib import pyplot as plt
cap = cv2.VideoCapture()
while(1):
bleh, img = cap.read()
laplacian = cv2.Laplacian(img,cv2.CV_64F)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()
However, I am getting an error stating that Image data can not be converted to float.
This program works when I replace the video capturing with just an image and feed that directly into the laplacian, sobelx, and sobely transformations.
Can I not sure matplot for video?
I had the same problem with your code then I changed :
cap = cv2.VideoCapture()
to :
cap = cv2.VideoCapture(0)
and it worked
This is because VideoCapture needs to know what video device to use on your computer, if you are using your webcam then you have to pass 0 as argument to the function