I'm making a class to make a nicer "thumbnail" for a picture.
The functions works fine, but inside the class I got the "object" has no "attribute 'thumbnail'". I'm not an expert on classes, but maybe a short recommendation? The "open" method worked fine!
class ResizeImage:
from PIL import Image
def newImage(self,dimensiune):
NouaPoza = Image.new('RGBA', (dimensiune, dimensiune), (255, 255, 255, 0))
self.thumbnail((dimensiune, dimensiune), Image.ANTIALIAS)
coordonateCentrare = ((dimensiune - self.size[0]) // 2, (dimensiune - self.size[1]) // 2)
NouaPoza.paste(self,coordonateCentrare)
return NouaPoza
def openVechi(self,fisier_in):
self = Image.open(fisier_in)
return self
def saveNou(self,fisier_out):
self.save(fisier_out)
if __name__ == '__main__':
fisier_in = "[...]"
fisier_out = "[...]"
poza = ResizeImage()
poza.openVechi(fisier_in)
poza.newImage(500)
poza.saveNou(fisier_out)
Thank you in advance!
P.S. Working just with functions was ok, like:
def thumbnail(poza,dimensiune):
poza.thumbnail((dimensiune,dimensiune),Image.ANTIALIAS)
EDIT
I believe the right declaration is:
class ResizeImage(Image.Image):
def newImage(self,dimensiune):
self.thumbnail((dimensiune,dimensiune),Image.ANTIALIAS)
BUT I get the following error:
File "C:/Users/claudiu.ivanescu/PycharmProjects/eDX/NewImage.py", line 11, in newImage
self.thumbnail((dimensiune,dimensiune),Image.ANTIALIAS)
File "C:\Users\claudiu.ivanescu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\PIL\Image.py", line 2059, in thumbnail
x, y = self.size
AttributeError: 'ResizeImage' object has no attribute 'size'
After some researching I renounce to make the class as before. I put all the details as attributes for object. And all the other method I access them without args.
There is the new class:
class resizeImage:
def __init__(self,dimension,fileIn,fileOut)
[...]
def createThumbnail(self):
from PIL import Image
picture = Image.open(self.fileIn)
[...]
thumbnail.save(self.fileOut)
def delThumbnail(self):
import os,sys
os.remove(self.fileOut)
Maybe will be useful for some people!
Related
i write this code in vscode :
from fileinput import filename
import imp
import cv2,time,os,tensorflow as tf
import numpy as np
from tensorflow.python.keras.utils.data_utils import get_file
np.random.seed(123)
class Detector:
def __init__(self) -> None:
pass
def readClaassees(self,classesFilePath):
with open(classesFilePath,'r') as f:
self.classesList = f.read().splitlines()
#colors list
self.colorList =np.random.uniform(low=0,high=255,size=(len(self.classesList),3))
print(len(self.classesList),len(self.colorList))
def downloadModel(self,modelURL):
fileName= os.path.basename(modelURL)
self.modelName =fileName[:fileName.index('.')]
self.cacheDir ="./pretrained_model"
os.makedirs(self.cacheDir,exist_ok=True)
get_file(fname=fileName,origin=modelURL,cache_dir=self.cacheDir,cache_subdir="checkpoints",extract=True)
def loadModel(self):
print("Loading Model "+self.modelName)
#tf.keras.backend.clear_session()
self.model = tf.saved_model.load(os.path.join(self.cacheDir,"checkpoints",self.modelName,"saved_model"))
print("Model"+self.modelName+"loaded successfully...")
def createBoundinBox(self,image):
inputTensor = cv2.cvtColor(image.copy(),cv2.COLOR_BGR2RGB)
inputTensor = tf.convert_to_tensor(inputTensor,dtype=tf.uint8)
inputTensor = inputTensor[tf.newaxis,...]
detections = self.model(inputTensor)
bboxs = detections['detection_boxes'][0].numpy()
classIndexes = detections['detection_classes'][0].numpy().astype(np.int32)
classScores = detections['detection_scores'][0].numpy
imH,imW,imC =image.shape
if len(bboxs) != 0 :
for i in range(0,len(bboxs)):
bbox = tuple(bboxs[i].tolist())
classConfidence = classScores[i]
classIndex = classIndexes[i]
classLblelText = self.classesList[classIndex]
classColor = self.colorList[classIndex]
displayText ='{}: {}%'.format(classLblelText,classConfidence)
ymin, xmin, ymax, xmax = bbox
print(ymin,xmin,ymax,xmax)
break
def pedictImage(self,imagePath):
image = cv2.imread(imagePath)
self.createBoundinBox(image)
cv2.imshow("result",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
and i got this error after run the method self.createBoundinBox(image) in the main:
File "d:\TensorflowObjectDetection\Detector.py", line 60, in createBoundinBox
classConfidence = classScores[i]
TypeError: 'method' object is not subscriptable.
does anyone know how to solve it ,please help .
I think its because you forgot the brackets in this line
classScores = detections['detection_scores'][0].numpy
I think it should be:
classScores = detections['detection_scores'][0].numpy()
When you call it without the brackets you are calling a method or a function which you cannot subscript like this method[]. That is what the error is telling you.
I'm going to take a wild guess here, and say that the line that declares classScores, which is currently this:
classScores = detections['detection_scores'][0].numpy
should be this:
classScores = detections['detection_scores'][0].numpy().astype(np.int32)
in this context, the .numpy is a method that you call, which itself is not subscriptable, meaning that you can't use index notation on it. This makes sense because again, it's a method, and not an array or list or whatever.
So I want a window that updates a shown picture after clicking.
It works fine as long as there is no further tk.Tk() instance (remove/add line 8 of the code below).
If one is created before, this error is raised:
line 29, in CreatePeakSelectionWindow
[...]
self.imgCanvas.create_image((0,0),anchor=tk.NW,image=self.img1)
[...]
_tkinter.TclError: image "pyimage1" doesn't exist
I think I need to pass some argument to Tk()?
I don't know where to even look to address this issue and understand how it is caused.
Sadly this widget is to be used to allow manual selection of some peaks and should be done in an external window.
FYI all arrays are dummies (random arrays) for simplicities sake.
Thank you very much for any help!
The code which causes the issue is the following:
import tkinter as tk
import numpy as np
from PIL import Image,ImageTk
import matplotlib.pyplot as plt
class Dummy:
def __init__(self):
self.MainWin = tk.Tk() #>this line causes the issue
imgs = np.random.randint(0,255,(512,624,2))
self.img = imgs[:,:,0] #self.img is a numpy array in black and white
self.imgSize = self.img.shape
self.peakList = np.array([[200,200],[300,400]])
self.selectedIndexOfPeaksList = []
self.peakListGenerated = True
def CreatePeakSelectionWindow(self):
if self.peakListGenerated:
self.selectedIndexOfPeaksList = []
self.PeakSelectionWindow = tk.Tk()
self.PeakSelectionWindow.protocol("WM_DELETE_WINDOW",self.PeakSelectionWindowClose)
self.PeakSelectionWindow.geometry("%sx%s"%(self.imgSize[1],self.imgSize[0]))
self.PeakSelectionWindow.title("Peak Slection")
self.img1 = ImageTk.PhotoImage(image=Image.fromarray(self.img))
self.imgCanvas = tk.Canvas(self.PeakSelectionWindow,width=self.imgSize[1],height=self.imgSize[0])
self.imgCanvas.place(x=0,y=0)
self.PeakSelectionWindow.bind("<Button 1>",self.LeftClick)
self.PeakSelectionWindow.bind("<Button 3>",self.RightClick)
self.PeakSelectionWindow.update()
self.imgCanvas.create_image((0,0),anchor=tk.NW,image=self.img1)
else:
print("List of peaks has not yet been generated!",file=sys.stderr)
def PeakSelectionWindowClose (self):
if len(self.selectedIndexOfPeaksList) > 0:
print("put extraction here")
#self.selectedPeaksEntry.insert(tk.END,", ".join(map(str,self.selectedIndexOfPeaksList)))
self.PeakSelectionWindow.destroy()
def LeftClick(self,event):
distance = np.sqrt((self.peakList[:,1]-event.x)**2+(self.peakList[:,0]-event.y)**2)
index = np.argmin(distance)
if index not in self.selectedIndexOfPeaksList:
self.peakList[index]
self.selectedIndexOfPeaksList += [index]
newImg = np.random.randint(0,255,(self.img.shape[0],self.img.shape[1],3))
self.PeakSelectionWindow.newImg = img = ImageTk.PhotoImage(image=Image.fromarray(newImg.astype("uint8"),mode="RGB"))
self.imgCanvas.delete("all")
self.imgCanvas.create_image((0,0),anchor=tk.NW,image=self.PeakSelectionWindow.newImg)
self.imgCanvas.update()
def RightClick (self,event):
distance = np.sqrt((self.peakList[:,1]-event.x)**2+(self.peakList[:,0]-event.y)**2)
index = np.argmin(distance)
print(self.selectedIndexOfPeaksList)
if index in self.selectedIndexOfPeaksList:
if len(self.selectedIndexOfPeaksList) > 1:
self.selectedIndexOfPeaksList.remove(index)
newImg = np.random.randint(0,255,(self.img.shape[0],self.img.shape[1],3))
self.PeakSelectionWindow.newImg = img = ImageTk.PhotoImage(image=Image.fromarray(newImg.astype("uint8"),mode="RGB"))
self.imgCanvas.delete("all")
self.imgCanvas.create_image((0,0),anchor=tk.NW,image=self.PeakSelectionWindow.newImg)
self.imgCanvas.update()
else:
self.selectedIndexOfPeaksList = []
self.PeakSelectionWindow.newImg = newImg = ImageTk.PhotoImage(image=Image.fromarray(self.img.astype("uint8")))
self.imgCanvas.delete("all")
self.imgCanvas.create_image((0,0),anchor=tk.NW,image=self.PeakSelectionWindow.newImg)
self.imgCanvas.update()
if __name__ == "__main__":
window = Dummy()
window.CreatePeakSelectionWindow()
tk.mainloop()
Okay so I found a solution.
The additional window needs to be a class with tk.Toplevel().
All changes for the code above are:
class Dummy: to class Dummy (tk.Toplevel()):
def __init__(self): to def __init__ (self,master):
self.peakSelectionWindow to self (as a reference to master
passed to the class)
any tk object (like buttons) also needs this master set as the window too to be rendered
Of course the creation of the first window should be handled outside of the class, passing the windowName = tk.Tk() onto the call of Dummy like a normal variable/reference.
In case you need to share variables of the master to this dummy class, I think windowName.variableName = 5 makes them known/accessable in dummy too (via self.variableName). However this might be messy, so instead pass them on normally if possible.
I get error when I print the result of a function in the main file (named as INPUT.py). The functions are made in another file (named as ENGINE.py). The error is: AttributeError: module 'ENGINE' has no attribute 'cross_section'
I cannot understand why do I get such error.
Here the code example:
#-- Main file: INPUT.py
class Duct:
def __init__(self, width, height):
self.width = width
self.height = height
Duct_ret = Duct(0.1, 0.1)
Duct_ret.width= 0.4
Duct_ret.height= 0.3
import ENGINE as EN
print(EN.cross_section)
#-- Engine file: ENGINE.py
from INPUT import width, height
def cross_section(self,):
c_s=height*width
return c_s
Error: AttributeError: module 'ENGINE' has no attribute 'cross_section'
This is happening because you have a circular dependency in your code.
In ENGINE.py, you import height and width and in INPUT.py you import ENGINE.
You should pass Duct_ret.height and Duct_ret.width to your helper function instead of importing it.
So instead of this:
import ENGINE as EN
print(EN.cross_section)
do this:
import ENGINE as EN
print(EN.cross_section(Duct_ret.height, Duct_ret.width))
and in ENGINE.py, define the function like this:
def cross_section(height, width):
c_s = height * width
return c_s
NOTE: you also have self as an argument to cross_section which isn't right since cross_section is not a class method -- you just need to pass the relevant arguments to the function (which your original code didn't).
Side note: you should move your import to the start of the file in INPUT.py for better style in this case.
#costaparas has given a very detailed answer.
I also played around with the given code to find a solution. While trying to figure this out, I found there are 2 issues with your code:
You shouldn't be using import to get class variables in a different file.
You are using top level imports in both files with circular dependency which is causing the error.
Solution:
INPUT1.py
class Duct:
def __init__(self, width, height):
self.width = width
self.height = height
Duct_ret = Duct(0.1, 0.1)
Duct_ret.width= 0.4
Duct_ret.height= 0.3
from ENGINE import cross_section1 as cs
cs(Duct_ret.width, Duct_ret.height)
ENGINE.py
def cross_section1(width,height):
c_s=height*width
print (c_s)
Reference doc for UploadedFile.
Reference for #fixture.
Trying to change the file size in the test case.
from django.core.files.uploadedfile import UploadedFile
class Mixin(object):
#fixture
def photo(self):
file_obj = StringIO()
image = Image.new("RGBA", size=(50, 50), color=(256, 0, 0))
image.save(file_obj, "png")
file_obj.seek(0)
return UploadedFile(file_obj, name="test.png", content_type="image/jpg", size=2000000)
I tried to change the file size for a test case
self.photo.size = 10000001
class Test(Mixin):
#fixture
def data(self):
return {"photo": self.photo}
def test_invalid_photo_size(self):
self.photo.size = 10000001
response = self.client.post(reverse("registration_register"), data=self.data)
But when I fetch value for the photo in the form, I'm getting the value i.e 144.
self.cleaned_data.get('photo').size
It should have returned the 10000001 as size in the form. I'm not clear why this is happening? Any alternative way, other than creating a new photo from scratch.
Here's my code:
from PIL import Image
from pilkit.processors import ResizeToFit
def before_saving_shop(sender, instance, **kwargs):
img = Image.open(instance.logo)
processor = ResizeToFit(100, 100)
instance.logo = processor.process(img)
pre_save.connect(before_saving_shop, sender=Shop)
I am getting this exception:
Exception Value: _committed
Please help.
You no need use signal for this purpose. Just redefine save method of the Shop model like this:
class Shop(models.Model):
....
def save(self):
img = Image.open(self.logo)
processor = ResizeToFit(100, 100)
self.logo = processor.process(img)
super(Shop, self).save()