CV2 saves pictures in BlackNWhite - python

I'm trying to send a picture with sockets module and pickles. It goes ok, but received picture is a bnw... could someone please tell me, which part I'm doing wrong?
first set parameters:
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY)]
read the file
img = cv2.imread('th.jpg', 0)
encode it
ret, img = cv2.imencode('.jpg', img, encode_param)
dump and after that send it with pickles to my client side
msg = pickle.dumps(img, 0)
on my client side - open it, decode it and write to file
frame=pickle.loads(message, fix_imports=True, encoding="bytes")
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
cv2.imwrite(f'{message_header}.jpg',frame)
but the saved file is bnw.... Where could be the problem?

Problem is with this line. img = cv2.imread('th.jpg', 0) change it to the following.
img = cv2.imread('th.jpg', 1)
According to the documentation, argument 0 in imread relates to grayscale and 1 relates to colour image.

Related

cv2.imdecode() returns None from image in base64, mimetype image/jpeg received via Websockets

I use websockets to receive video frames. Image is encoded in base64 mimetype image/jpeg. I'm trying to convert image to np.ndarray. When I read image file code works correct. But when I'm trying to read image from socket stream, issue is occured.
image_data = base64.b64decode(part.encoded_image)
np_array = np.frombuffer(image_data, np.uint8)
image = cv2.imdecode(np_array, cv2.IMREAD_UNCHANGED)
In docs cv2.imdecode() returns None in case when image is short or corrupted. My image is in HD format, 1280/720. Data isn't corrupted as I could successfully decode it using online converter.
This is the beginning of received data:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/
You have to skip data:image/jpeg;base64, to get only base64 data which will give you correct image data and cv2 will decode and display it.
In example I use split(',', 1) for this - it gives me data:image/jpeg;base64, in variable header and image data in data.
I use full image in code.
import base64
import numpy as np
import cv2
encoded_image = 'data:image/jpeg;base64,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'
header, data = encoded_image.split(',', 1)
#print('header:', header)
#print(' data:', data[:20])
image_data = base64.b64decode(data)
#print('result:', image_data[:20])
np_array = np.frombuffer(image_data, np.uint8)
#print(' array:', np_array[:2])
image = cv2.imdecode(np_array, cv2.IMREAD_UNCHANGED)
#print(' image:', image[:2])
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
(face image with size 7x7)

How to extract text from webcam image

I am trying to extract text from the image taken by webcam. My code is below :
from PIL import Image
from pytesseract import image_to_string
import cv2
import time
cap = cv2.VideoCapture(0)
time.sleep(3)
ret, frame = cap.read()
if ret != True:
raise ValueError("Can't read frame")
cv2.imwrite('img2.png', frame)
cv2.imshow("img1", frame)
cv2.waitKey()
cv2.destroyAllWindows()
img = Image.open('img2.png')
text = image_to_string(img, lang='eng')
print(text)
I could extract text from screen shot image and now trying same thing in terms of webcam.
I just attempted to take photo with webcam and the download image taken by webcam and used image_to_string() to extract text from that image.
But it does not return any text even though the image is correctly taken.
How should I edit this ?
Otherwise, if you have any other good idea, I would like to know.

how to display PIL image with pygame?

I am trying to do some video stream from my raspberry pi over the wifi. I used pygame, because i also have to use gamepad in my project. Unfortunately I stucked on displaying received frame. Shortly: i get jpeg frame, open it with PIL, convert to string - after that i can load image from string
image_stream = io.BytesIO()
...
frame_1 = Image.open(image_stream)
f = StringIO.StringIO()
frame_1.save(f, "JPEG")
data = f.getvalue()
frame = pygame.image.fromstring(frame_1,image_len,"RGB")
screen.fill(white)
screen.blit(frame, (0,0))
pygame.display.flip()
and error is :
Traceback (most recent call last):
File "C:\Users\defau_000\Desktop\server.py", line 57, in <module>
frame = pygame.image.fromstring(frame_1,image_len,"RGB")
TypeError: must be str, not instance
Sloth's answer is incorrect for newer versions of Pygame. The tostring() definition is deprecated. Here is a working variant for Python 3.6, PIL 5.1.0, Pygame 1.9.3:
raw_str = frame_1.tobytes("raw", 'RGBA')
pygame_surface = pygame.image.fromstring(raw_str, size, 'RGBA')
The first argument to pygame.image.fromstring has to be a str.
So when frame_1 is your PIL image, convert it to a string with tostring, and load this string with pygame.image.fromstring.
You have to know the size of the image for this to work.
raw_str = frame_1.tostring("raw", 'RGBA')
pygame_surface = pygame.image.fromstring(raw_str, size, 'RGBA')

How can I capture a picture from webcam and send it via flask

I want to send an Image object in a flask response but it gives me an error. I tried also an approach with StringIO.
image = Image.open("./static/img/test.jpg")
return send_file(image, mimetype='image/jpeg')
This is just a test case. So the major problem is to capture an image from /dev/video0 and sent it (ideally without temporary storing on disk) to the client. I use v4l2capture for that. The test picture should also work if you may have a better solution for that task.
import select
import v4l2capture
video = v4l2capture.Video_device("/dev/video0")
size_x, size_y = video.set_format(1280, 1024)
video.create_buffers(1)
video.queue_all_buffers()
video.start()
select.select((video,), (), ())
image_data = video.read()
video.close()
image = Image.fromstring("RGB", (size_x, size_y), image_data)
Thanks.
EDIT
Works now. Better solutions as v4l2capture are welcome...
Did it with.
image = Image.open("./static/img/test.jpg")
img_io = StringIO()
image.save(img_io, 'JPEG', quality=70)
img_io.seek(0)
return send_file(img_io, mimetype='image/jpeg')

Upload Image To Imgur After Resizeing In PIL

I am writing a script which will get an image from a link. Then the image will be resized using the PIL module and the uploaded to Imgur using pyimgur. I dont want to save the image on disk, instead manipulate the image in memory and then upload it from memory to Imgur.
The Script:
from pyimgur import Imgur
import cStringIO
import requests
from PIL import Image
LINK = "http://pngimg.com/upload/cat_PNG106.png"
CLIENT_ID = '29619ae5d125ae6'
im = Imgur(CLIENT_ID)
def _upload_image(img, title):
uploaded_image = im.upload_image(img, title=title)
return uploaded_image.link
def _resize_image(width, height, link):
#Retrieve our source image from a URL
fp = requests.get(link)
#Load the URL data into an image
img = cStringIO.StringIO(fp.content)
im = Image.open(img)
#Resize the image
im2 = im.resize((width, height), Image.NEAREST)
#saving the image into a cStringIO object to avoid writing to disk
out_im2 = cStringIO.StringIO()
im2.save(out_im2, 'png')
return out_im2.getvalue()
When I run this script I get this error: TypeError: file() argument 1 must be encoded string without NULL bytes, not str
Anyone has a solution in mind?
It looks like the same problem as this, and the solution is to use StringIO.
A common tip for searching such issues is to search using the generic part of the error message/string.

Categories