st.write("Preview")
#openCV image result cropped_image which is an np array
st.image(cropped_image)
#cropped_image converted to PIL image color
result = Image.fromarray(cropped_image.astype('uint8'), 'RGB')
img = Image.open(result)
btn = st.download_button(
label="Download image",
data=img,
file_name="imagename.png",
mime="image/png")
I want to use st.download_button to download the image result. I know I cannot use the cropped_image result since it is an np array. I converted the image array to a PIL image but I don't know how I can get the result image filename from here . Could you please give me some ideas how to solve this issue?
The Streamlit download_button expects the data type to be a certain type. Read more here: https://github.com/streamlit/streamlit/blob/ba46ad297e8816f0d6a3aa910ce67556239f3e6d/lib/streamlit/elements/button.py#L353
You can convert your PIL Image to bytes using the following snippet:
from io import BytesIO
buf = BytesIO()
img.save(buf, format="JPEG")
byte_im = buf.getvalue()
Now you can use the st.download_button
btn = col.download_button(
label="Download Image",
data=byte_im,
file_name="imagename.png",
mime="image/jpeg",
)
If you have the image file in your directory:
st.download_button(label='Download Image',
data= open('yourimage.png', 'rb').read(),
file_name='imagename.png',
mime='image/png')
Related
I am trying to create a layer on a DICOM image, below code works fine for jpg/png images but not for DICOM.
import cv2
import numpy as np
import pydicom as dicom
ds=dicom.dcmread('D0009.dcm')
img=ds.pixel_array
blank = np.zeros(shape=(img.shape[0],img.shape[1],3), dtype=np.uint8)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(blank,
text='Logo',
org=(img.shape[1]//8, img.shape[0]//2),
fontFace=font,
fontScale= 2,color=(163,163,163),
thickness=11,
lineType=cv2.LINE_4)
blend=cv2.addWeighted(img,0.7,blank,1, 0, dtype = cv2.CV_32F)
cv2.imshow('sample image dicom',blend)
cv2.waitKey()
any help would be apreciated
I was able to get this working by normalizing the value range of the DICOM image and converting the DICOM image from greyscale to RGB image. Replace your line
img=ds.pixel_array
with these lines:
img = np.array(ds.pixel_array, dtype='float32')
img /= np.max(img)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
I am trying to crop an image with cv2 (converting it to a bytes file and therefore not needing to save it)and afterwards perform pytesseract.
This way i won't need to save the image twice during the process.
First when i create the image
When cropping the image
Process...
## CROPPING THE IMAGE REGION
ys, xs = np.nonzero(mask2)
ymin, ymax = ys.min(), ys.max()
xmin, xmax = xs.min(), xs.max()
croped = image[ymin:ymax, xmin:xmax]
pts = np.int32([[xmin, ymin],[xmin,ymax],[xmax,ymax],[xmax,ymin]])
cv2.drawContours(image, [pts], -1, (0,255,0), 1, cv2.LINE_AA)
#OPENCV IMAGE TO BYTES WITHOUT SAVING TO DISK
is_success, im_buf_arr = cv2.imencode(".jpg", croped)
byte_im = im_buf_arr.tobytes()
#PYTESSERACT IMAGE USING A BYTES FILE
Results = pytesseract.image_to_string(byte_im, lang="eng")
print(Results)
Unfortunately i get the error : Unsupported image object
Am i missing something? Is there a way to do this process without needing to save the file when cropping? Any help is highly appreciated.
you have croped which is a numpy array.
according to pytesseract examples, you simply do this:
# tesseract needs the right channel order
cropped_rgb = cv2.cvtColor(croped, cv2.COLOR_BGR2RGB)
# give the numpy array directly to pytesseract, no PIL or other acrobatics necessary
Results = pytesseract.image_to_string(cropped_rgb, lang="eng")
from PIL import Image
img_tesseract = Image.fromarray(croped)
Results = pytesseract.image_to_string(img_tesseract, lang="eng")
from PIL import Image
import io
def bytes_to_image(image_bytes):
io_bytes = io.BytesIO(image_bytes)
return Image.open(io_bytes)
pytesseract.image_to_data(byte_array_image,lang='eng')
I'm trying to extract images from a pdf using PyPDF2, but when my code gets it, the image is very different from what it should actually look like, look at the example below:
But this is how it should really look like:
Here's the pdf I'm using:
https://www.hbp.com/resources/SAMPLE%20PDF.pdf
Here's my code:
pdf_filename = "SAMPLE.pdf"
pdf_file = open(pdf_filename, 'rb')
cond_scan_reader = PyPDF2.PdfFileReader(pdf_file)
page = cond_scan_reader.getPage(0)
xObject = page['/Resources']['/XObject'].getObject()
i = 0
for obj in xObject:
# print(xObject[obj])
if xObject[obj]['/Subtype'] == '/Image':
if xObject[obj]['/Filter'] == '/DCTDecode':
data = xObject[obj]._data
img = open("{}".format(i) + ".jpg", "wb")
img.write(data)
img.close()
i += 1
And since I need to keep the image in it's colour mode, I can't just convert it to RBG if it was CMYK because I need that information.
Also, I'm trying to get dpi from images I get from a pdf, is that information always stored in the image?
Thanks in advance
I used pdfreader to extract the image from your example.
The image uses ICCBased colorspace with the value of N=4 and Intent value of RelativeColorimetric. This means that the "closest" PDF colorspace is DeviceCMYK.
All you need is to convert the image to RGB and invert the colors.
Here is the code:
from pdfreader import SimplePDFViewer
import PIL.ImageOps
fd = open("SAMPLE PDF.pdf", "rb")
viewer = SimplePDFViewer(fd)
viewer.render()
img = viewer.canvas.images['Im0']
# this displays ICCBased 4 RelativeColorimetric
print(img.ColorSpace[0], img.ColorSpace[1].N, img.Intent)
pil_image = img.to_Pillow()
pil_image = pil_image.convert("RGB")
inverted = PIL.ImageOps.invert(pil_image)
inverted.save("sample.png")
Read more on PDF objects: Image (sec. 8.9.5), InlineImage (sec. 8.9.7)
Hope this works: you probably need to use another library such as Pillow:
Here is an example:
from PIL import Image
image = Image.open("path_to_image")
if image.mode == 'CMYK':
image = image.convert('RGB')
image.write("path_to_image.jpg")
Reference: Convert from CMYK to RGB
Disaster!
As you can see, the image isn't quite loaded correctly. The original:
The code:
import cv2
import imutils
a=imutils.url_to_image("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", readFlag=-1)
cv2.imshow("goog", a)
cv2.waitKey()
The implementation of url_to_image in imutils:
def url_to_image(url, readFlag=cv2.IMREAD_COLOR):
# download the image, convert it to a NumPy array, and then read
# it into OpenCV format
resp = urlopen(url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, readFlag)
# return the image
return image
I also tried readFlag=cv2.IMREAD_UNCHANGED, but that didn't do the trick either.
please send help
alright gang we did it
so I tried another version of displaying:
plt.figure("Correct")
plt.imshow(imutils.opencv2matplotlib(a))
plt.show()
No luck it would appear. But then, looking into the opencv2matplotlib source, we find:
def opencv2matplotlib(image):
# OpenCV represents images in BGR order; however, Matplotlib
# expects the image in RGB order, so simply convert from BGR
# to RGB and return
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
Aha, but we have 4 channel color (alpha), so by common sense we need cv2.COLOR_BGRA2RGBA not cv2.COLOR_BGR2RGB!!
Testing this theory:
plt.figure("Correct")
plt.imshow(cv2.cvtColor(a, cv2.COLOR_BGRA2RGBA))
plt.show()
We get...
Whoop dee doop!
# import the necessary packages
import numpy as np
import urllib
import cv2
def url_to_image(url):
# download the image, convert it to a NumPy array, and then read
# it into OpenCV format
resp = urllib.request.urlopen(url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
# return the image
return image
# initialize the list of image URLs to download
url="http://i.dailymail.co.uk/i/pix/2015/09/01/18/2BE1E88B00000578-3218613-image-m-5_1441127035222.jpg"
print ("downloading %s" % (url))
image = url_to_image(url)
cv2.imshow("Image", image)
cv2.waitKey(0)
And the output is:
I'm trying to resize an image to 500x500px but got this error:
File "C:\Python27\lib\site-packages\PIL\Image.py", line 1681, in save
save_handler = SAVE[format.upper()] KeyError: 'JPG'
This is the code:
from PIL import Image
img = Image.open('car.jpg')
new_img = img.resize((500,500))
new_img.save('car_resized','jpg')
You need to set the format parameter in your call to the save function to 'JPEG':
from PIL import Image
img = Image.open('car.jpg')
new_img = img.resize((500,500))
new_img.save("car_resized.jpg", "JPEG", optimize=True)
Here is the solution:
from PIL import Image
img = Image.open('car.jpg')
new_img = img.resize((500,500), Image.ANTIALIAS)
quality_val = 90 ##you can vary it considering the tradeoff for quality vs performance
new_img.save("car_resized.jpg", "JPEG", quality=quality_val)
There are list of resampling techniques in PIL like ANTIALIAS, BICUBIC, BILINEAR and CUBIC.
ANTIALIAS is considered best for scaling down.