OpenCV does not accept ndarray to TextDecectorCNN.detect() - python

I am trying to use this OpenCV class of text detector to find out if I can use it for my project. I am loaging image like this:
src = cv2.imread(img_path)
And then I am trying to use function mentioned before like this:
bbox, confidence = cv2.text_TextDetectorCNN.detect(src)
But this code falls with the following mistake:
TypeError: descriptor 'detect' for 'cv2.text_TextDetectorCNN' objects doesn't apply to a 'numpy.ndarray' object
I have already tried to use image = cv2.cvtColor(src, cv2.COLOR_BGR2RGB, cv2.CV_8UC3) but it doesn't do a thing - image remains an ndarray.
UPD: Attaching whole code and problematic picture.
import os
# borrowed from https://github.com/lengstrom/fast-style-transfer/blob/master/src/utils.py
def list_images(in_path, formats=[".jpg", ".jpeg", ".gif", ".png", ".pgm", ".bmp"]):
img_files = []
for (dirpath, _, filenames) in os.walk(in_path):
for file in filenames:
_, ext = os.path.splitext(file)
ext = str.lower(ext)
if ext in formats:
img_files.append(os.path.join(dirpath, file))
return img_files
def test_accuracy(folder_path):
image_list = list_images(folder_path)
for img_path in image_list:
src = cv2.imread(img_path)
bbox, confidence = cv2.text_TextDetectorCNN.detect(src)
print(img_path, bbox, confidence) # To check format of output
Tested image:
(I've tested 3 different .jpg images, none of them worked)
Question: is there a way to convert ndarray into some OpenCV format that will be accepted by mentioned function?

Your problem is that you don't create an instance of your text detector. See this:
import cv2
import numpy as np
# After downloading the caffemodel and
# textbox.prototxt you have to create
# an instance of your model
textSpotter = cv2.text.TextDetectorCNN_create(
"textbox.prototxt", "TextBoxes_icdar13.caffemodel"
)
src = cv2.imread("1.png")
bbox, confidence = textSpotter.detect(src)
print("HELLO", bbox, confidence) # To check format of output

Related

Stitching multiple pngs into a h5 image h5py

I created an model in blender. From here I took 2d slices through the y-plane of that model leading to the following.
600 png files each corresponding to a ylocation i.e y=0, y=0.1 etc
Each png file has a resolution of 500 x 600.
I am now trying to merge the 600 pngs into a h5 file using python before loading the .h5 into some software. I find that each individual png file is read fine and looks great. However when I look at the final 3d image there is some stretching of the image, and im not sure how this is being created.
The images are resized (from 600x600 to 500x600, but I have checked and this is not the cause of the stretching). I would like to know why I am introducing such stretching in other planes (not y-plane).
Here is my code, please note that there is some work in progress here, hence why I append the dataset to a list (this is to be used for later code)
from PIL import Image
import sys
import os
import h5py
import numpy as np
import cv2
from datetime import datetime
dir_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(dir_path + '//..//..')
Xlen=500
Ylen=600
Zlen=600
directory=dir_path+"/LowPolyA21/"
for filename in os.listdir(directory):
if fnmatch.fnmatch(filename, '*.png'):
image = Image.open(directory+filename)
new_image = image.resize((Zlen, Xlen))
new_image.save(directory+filename)
dataset = np.zeros((Xlen, Zlen, Ylen), np.float)
# traverse all the pictures under the specified address
cnt_num = 0
img_list = sorted(os.listdir(directory))
os.chdir(directory)
for img in (img_list):
if img.endswith(".png"):
gray_img = cv2.imread(img, 0)
dataset[:, :, cnt_num] = gray_img
cnt_num += 1
dataset[dataset == 0] = -1
dataset=dataset.swapaxes(1,2)
datasetlist=[]
datasetlist.append(dataset)
dz_dy_dz = (float(0.001),float(0.001),float(0.001))
for j in range(Xlen):
for k in range(Ylen):
for l in range(Zlen):
if datasetlist[i][j,k,l]>1:
datasetlist[i][j,k,l]=1
now = datetime.now()
timestamp = now.strftime("%d%m%Y_%H%M%S%f")
out_h5_path='voxelA_'+timestamp+'_flipped'
out_h5_path2='voxelA_'+timestamp+'_flipped.h5'
with h5py.File(out_h5_path2, 'w') as f:
f.attrs['dx_dy_dz'] = dz_dy_dz
f['data'] = datasetlist[i] # Write data to the file's primary key data below
Example of image without stretching (in y-plane)
Example of image with stretching (in x-plane)

how to convert a nift folder to png images?

*library
there is a mostly known library imported from NumPy and imageio
import NumPy as np
import os
import nibabel as nib
import imageio
// method where I have I write code to convert a nift to png
Method
convert a nift(.nii) image to png image
def nii_to_image(niifile):
filenames = os.listdir(filepath) #read nii folder
slice_trans = []
#filename is the path of nii image
for f in filenames:
#Start reading nii files
img_path = os.path.join(filepath, f)
img = nib.load(img_path) #read nii
img_fdata = img.get_fdata()
fname = f.replace('.nii','')
# Remove the nickname of nii
img_f_path = os.path.join(imgfile, fname)
#Create a folder corresponding to the image of nii
if not os.path.exists(img_f_path):
os.mkdir(img_f_path) #New folder
# to image
(x,y,z) = img.shape
for i in range(z): #x is the sequence of images
silce = img_fdata[i, :, :] #Select which direction the slice can be
imageio.imwrite(os.path.join(img_f_path,'{}.png'.format(i)), silce) #Save image
#main function where fill path was gived
main
if __name__ == '__main__':
filepath = '/content/drive/MyDrive/sem 8/dataset/pr'
imgfile = '/content/drive/MyDrive/sem 8/dataset/propi'
nii_to_image(filepath)
After you load the nifti file as NumPy array as you did, run on every slice (z from img.shape) and then save the array to png.
Make sure that when you run on each slice you save only the existing one (the z_slice_number):
slice = img_fdata[:, :, z_slice_numer]
And to save this slice you can do as follow (or another way from here):
matplotlib.image.imsave('name.png', slice)

Trying to use multiple images in opencv imread function but not getting

import pprint as pp
original_img = cv2.imread("/content/drive/My Drive/images/image1.jpg") #here i want to use multiple images atleast 250 images.
original_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)
results = tfnet2.return_predict(original_img)
print(results)
I guess all your images are in the folder images. So you can use os to gett all their filenames.
import os
pth = "/content/drive/My Drive/images" # make sure it is correct
images = os.listdir(pth)
for image in images:
image_path = os.path.join(pth, image)
original_img = cv2.imread(image_path)
original_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)
results = tfnet2.return_predict(original_img)
print(results)
anyone can use for loop add empty folder to direct all the json files directly to the same folder using basic addition '+' operator.
for i in range():
original_img = cv2.imread("/folder path(500+ images)/" + any_empty_folder[i])

Python Image.open() does not recognize regular expression

from PIL import Image
image1 = "Image_I0000_F1_Filter 1_1A_health_2014-05-20_11.05.33.483.tiff"
image2 = "*F1*.tiff"
im1 = Image.open(image1)
im2 = Image.open(image2)
Tried to open the same image. im1 opens with no problem, but im2 shows IOError: [Errno 2] No such file or directory: '*F1*.tiff'.
Also tried
image2 = r"*F1*.tiff"
im2 = Image.open(image2)
and
image2 = "*F1*.tiff"
im2 = Image.open(open(image2,'rb'))
neither works.
PIL.Image.open has no glob matching. The documentation advises
You can use either a string (representing the filename) or a file object as the file argument
Notably not including glob matching.
Python uses the glob module to do glob matching.
from PIL import Image
import glob
filenames = glob.glob("*F1*.tiff")
# gives a list of matches, in this case most likely
# # ["Image_I0000_F1_Filter 1_1A_health_2014-05-20_11.05.33.483.tiff"]
if filenames:
filename = filenames[0]
else:
# what do we do if there's no such file? I guess pass the empty string
# to Image and let it deal with it
filename = ""
# or maybe directly...
raise FileNotFoundError
im1 = Image.open(filename)

How to complete this python function to save in the same folder?

I am trying to write my first real python function that does something real. What i want to accomplish is searching a given folder, and then open all images and merging them together so they make a filmstrip image. Imagine 5 images stacked on top of eachother in one image.
I have this code now, which should be pretty much ok, but propably needs some modification:
import os
import Image
def filmstripOfImages():
imgpath = '/path/here/'
files = glob.glob(imgpath + '*.jpg')
imgwidth = files[0].size[0]
imgheight = files[0].size[1]
totalheight = imgheight * len(files)
filename = 'filmstrip.jpg'
filmstrip_url = imgpath + filename
# Create the new image. The background doesn't have to be white
white = (255,255,255)
filmtripimage = Image.new('RGB',(imgwidth, totalheight),white)
row = 0
for file in files:
img = Image.open(file)
left = 0
right = left + imgwidth
upper = row*imgheight
lower = upper + imgheight
box = (left,upper,right,lower)
row += 1
filmstripimage.paste(img, box)
try:
filmstripimage.save(filename, 'jpg', quality=90, optimize=1)
except:
filmstripimage.save(miniature_filename, 'jpg', quality=90)")
How do i modify this so that it saves the new filmstrip.jpg in the same directory as I loaded the images from? And it probably has some things that are missing or wrong, anybody got a clue?
Related question: How to generate a filmstrip image in python from a folder of images?
It is not an answer to your question, but It might be helpful:
#!/usr/bin/env python
from PIL import Image
def makefilmstrip(images, mode='RGB', color='white'):
"""Return a combined (filmstripped, each on top of the other) image of the images.
"""
width = max(img.size[0] for img in images)
height = sum(img.size[1] for img in images)
image = Image.new(mode, (width, height), color)
left, upper = 0, 0
for img in images:
image.paste(img, (left, upper))
upper += img.size[1]
return image
if __name__=='__main__':
# Here's how it could be used:
from glob import glob
from optparse import OptionParser
# process command-line args
parser = OptionParser()
parser.add_option("-o", "--output", dest="file",
help="write combined image to OUTPUT")
options, filepatterns = parser.parse_args()
outfilename = options.file
filenames = []
for files in map(glob, filepatterns):
if files:
filenames += files
# construct image
images = map(Image.open, filenames)
img = makefilmstrip(images)
img.save(outfilename)
Example:
$ python filmstrip.py -o output.jpg *.jpg
I think if you change your try section to this:
filmstripimage.save(filmstrip_url, 'jpg', quality=90, optimize=1)
In the case you are not joking there are several problems with your script e.g. glob.glob() returns list of filenames (string objects, not Image objects) therefore files[0].size[0] will not work.
as J. F. Sebastian mentioned, glob does not return image objects... but also:
As it is right now, the script assumes the images in the folder are all the same size and shape. This is not often a safe assumption to make.
So for both of those reasons, you'll need to open the images before you can determine their size. Once you open it you should set the width, and scale the images to that width so there is no empty space.
Also, you didn't set miniature_filename anywhere in the script.

Categories

Resources