Image always renders as a gray box - python

When I load a set of image files into a list and try to display one, it always renders as a gray box.The images are not gray boxes. The size of the image window displayed by openCV varies with the size of the actual image on file.
import cv2
import glob
import random
def loadImages(path):
imdir = path
ext = ['png', 'jpg', 'gif'] # Add image formats here
files = []
[files.extend(glob.glob(imdir + '*.' + e)) for e in ext]
#print("files", files)
images = [cv2.imread(file) for file in files]
return images
images = loadImages("classPhotos/")
print(str(len(images)), "images loaded")
#print(images)
cv2.imshow("image", random.choice(images))
tmp = input()

Add this 2 lines after cv2.imshow("image", random.choice(images)) to make it work properly.
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imshow shows the image instantly and then doesn't show it.
cv2.waitKey waits for a specific time/ keeps showing the image.
putting 0 as an argument makes it wait infinitely unless a key is pressed.
cv2.destroyAllWindows() helps close the window otherwise it gets stuck.

Related

How to convert Clipboard Image BMP to PNG using Pillow package without saving and then loading

I would like to convert an image obtained from the Windows Clipboard to PNG format without having to save and then reload.
As per the code below, I am saving the clipboard image and then reloading it.
Is there a way to convert the image to PNG format without those extra steps, such that the
PIL.BmpImagePlugin.DibImageFile gets converted to
PIL.PngImagePlugin.PngImageFile
Here is the current code:
from PIL import ImageGrab, Image
# Get the clipboard image
img1 = ImageGrab.grabclipboard()
# Save the image from the clipboard to file
img1.save('paste.png', 'PNG')
print("Image Type1:", type(img1))
# Load the image back in
img2 = Image.open('paste.png')
print("Image Type2:", type(img2))
OUTPUT:
Image Type1: <class 'PIL.BmpImagePlugin.DibImageFile'>
Image Type2: <class 'PIL.PngImagePlugin.PngImageFile'>
As per some help from Seon's comment, this got me on the right track, and fulfilled my requirements.
As per Seon:
"the idea is to save the image to an in-memory BytesIO object, and reload it from there. We're still saving and loading, but not to disk."
Which is exactly what I wanted.
Here is the code I used:
from PIL import ImageGrab, Image
import io
def convertImageFormat(imgObj, outputFormat="PNG"):
newImgObj = imgObj
if outputFormat and (imgObj.format != outputFormat):
imageBytesIO = io.BytesIO()
imgObj.save(imageBytesIO, outputFormat)
newImgObj = Image.open(imageBytesIO)
return newImgObj
# Get the clipboard image and convert to PNG
img1 = ImageGrab.grabclipboard()
img2 = convertImageFormat(img1)
# Check the types
print("Image Type1:", type(img1))
print("Image Type2:", type(img2))
OUTPUT:
Image Type1: <class 'PIL.BmpImagePlugin.DibImageFile'>
Image Type2: <class 'PIL.PngImagePlugin.PngImageFile'>

Why is Python Open CV imwrite unable to save a simple image from my webcam?

My goal is to capture some images from my laptop's webcam to use them later. The main problem is that cv2.imwrite doesn't seem to work, the directory is created succesfully but I cannot find a way to save the image. I am currently on Manjaro Linux. I've alredy checked that the frame is not empty and in other Python scripts I've been able to show the image properly, the only problem seems to be when I try to save the image.
Is there any other way to save the image or is something wrong with my code?
I have the following Python code:
import cv2 #opencv
import os
import time
import uuid
IMAGES_PATH = 'Tensorflor/workspace/images/collectedimages'
labels = ['hola', 'gracias', 'si', 'no', 'tequiero']
img_number = 15
for label in labels:
!mkdir {'Tensorflow/workspace/images/collectedimages/'+label}
cap = cv2.VideoCapture(0)
print('Collecting images for {}'.format(label))
time.sleep(5)
for numimg in range(img_number):
ret, frame = cap.read()
img_name = os.path.join(IMAGES_PATH, label, label+'.'+'{}.jpg'.format(str(uuid.uuid1())))
cv2.imwrite(img_name,frame)
cv2.imshow('Frame',frame)
time.sleep(2)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()

Tesseract doesn't recognize characters(numbers)

I'm trying to read a water level from a photo file(jpg or png).
but Tesseract does not read any of character at all even I cut the all the unnecessary area of photo.
I put a print function at the end of the code to see recognized number, but nothing appeared.
enter image description here
Here is the photo I have and under neath is the Python code.
import cv2
import os
from PIL import Image
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'
image = cv2.imread ("water002.jpg")
#gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.Canny(image, 300, 350)
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)
text = pytesseract.image_to_string(Image.open(filename), lang=None)
#os.remove(filename)
print(text)
cv2.imshow("Image", image)
cv2.waitKey(0)
Is there any tip to let Tesseract to read the level or any other method?

How to extract numbers from a complex captcha

I am trying to resolve captcha for the following image
!https://ibb.co/35X723J
I have tried using tessaract
data = br.open(captchaurl).read()
b = bytearray(data)
save = open(filename, 'wb')
save.write(data)
save.close()
ctext= pytesseract.image_to_string(Image.open(filename))
Here is a workaround. You need to clear a bit the image but you wont get a perfect result. Try the following:
try:
from PIL import Image
except ImportError:
import Image
import pytesseract
import cv2
file = 'sample.jpg'
img = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, None, fx=10, fy=10, interpolation=cv2.INTER_LINEAR)
img = cv2.medianBlur(img, 9)
th, img = cv2.threshold(img, 185, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4,8))
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imwrite("sample2.jpg", img)
file = 'sample2.jpg'
text = pytesseract.image_to_string(file)
print(''.join(x for x in text if x.isdigit()))
Option 1:
I think using Pytesseract should solve the issue. I tried out your code and it gave me the following result when i gave in the exact cropped captcha image as input into pytesseract:
Input Image:
Output:
print(ctext)
'436359 oS'
I suggest you don't give the full page url as input into pytesseract. Instead give the exact image url as "https://i.ibb.co/RGn9fF5/Jpeg-Image-CS2.jpg" which will take in only the image.
And regarding the extra 'oS' characters in the output, you can do a string manipulation to chop off the characters other than numbers in the output.
re.sub("[^0-9]", "", ctext)
Option 2:
You can also use google's OCR to accomplish this which gives you the exact result without errors. Though I have shown you the web interface of it, google has nice python libraries through which you can accomplish this using python itself. Looks like this:

PIL isn't able to show images

I've been trying to show a image with PIL but I don't know why the image viewer keeps giving me this:"Windows photo viewer can't open this picture because either the picture is deleted,or it's in a location that isn't available.
I've checked the pic is on my desktop and doesn't have any problem.
Here is my code:
from PIL import Image
img = Image.open('photo_2016-08-04_22-38-11.jpg')
img.show()
Could any one help me with this?
Try this little snippet:
from PIL import Image
import os
home_path = os.path.expanduser('~')
filename = os.path.join(home_path,'Desktop','photo_2016-08-04_22-38-11.jpg')
if os.path.exists(filename):
print "Opening filename {0}".format(filename)
img = Image.open(filename)
img.show()
else:
print "Filename {0} doesn't exist".format(filename)

Categories

Resources