How to get loop to start on a mouse click in python - python

I am struggling to find a way to get my program to change the image to grayscale after the user clicks on the original image. The curly brackets are where I believe my problem is.
import image
img = image.Image("nature.jpg")
win = image.ImageWin(img.getWidth(), img.getHeight())
img.draw(win)
img.setDelay(1,15)
if {}:
for row in range(img.getHeight()):
for col in range(img.getWidth()):
p = img.getPixel(col, row)
aver = (p.getRed() + p.getGreen() + p.getBlue())/3
newred = aver
newgreen = aver
newblue = aver
newpixel = image.Pixel(newred, newgreen, newblue)
img.setPixel(col, row, newpixel)
img.draw(win)

Related

Try to Put Functions into one Button Tkinter

plz can someone help, i try to put functions into one button Tkinter but it didn't work. i try to do image color conversion manually with opencv formula. But when i try to run it with tkinter button it didn't nothing.
def convertBGRtoHSV(image):
path = filedialog.askopenfilename()
image = cv2.imread(path)
rows = image.shape[0]
cols = image.shape[1]
sample = (image * (1/255.0))
B,G,R = cv2.split(sample)
V = np.zeros((rows, cols)[:2],dtype=np.float64)
S = np.zeros((rows, cols)[:2],dtype=np.float64)
H = np.zeros((rows, cols)[:2],dtype=np.float64)
for i in range(rows):
for j in range(cols):
V[i,j] = max(B[i,j],G[i,j],R[i,j])
Min_RGB = min(B[i,j],G[i,j],R[i,j])
if V[i,j] != 0.0:
S[i,j] = ((V[i,j] - Min_RGB) / V[i,j])
else:
S[i,j] = 0.0
if V[i,j] == R[i,j]:
H[i,j] = 60*(G[i,j] - B[i,j])/(V[i,j] - Min_RGB)
elif V[i,j] == G[i,j]:
H[i,j] = 120 + 60*(B[i,j] - R[i,j])/(V[i,j] - Min_RGB)
elif V[i,j] == B[i,j]:
H[i,j] = 240 + 60*(R[i,j] - G[i,j])/(V[i,j] - Min_RGB)
if H[i,j] < 0:
H[i,j] = H[i,j] + 360
V = 255.0 * V
S = 255.0 * S
H = H/2
hsv = np.round(cv2.merge((H,S,V)))
return hsv.astype(np.uint8)
percobaan = convertBGRtoHSV(image)
H = crophsv[:,:,0] #Mengambil Nilai H pada Gambar
S = crophsv[:,:,1] #Mengambil Nilai S pada Gambar
V = crophsv[:,:,2] #Mengambil Nilai V pada Gambar
data = (H)
print(data)
btn = Button(gui, text='Select A Image', width=15,height=3, bd='5', command=[convertBGR2HSV()])
btn.place(x=500, y=650)
btn.pack
when i try running with opencv library tkinter button works and get all hue
the mode hue is all 0
when im using library opencv it work.may god bless anyone who help me. Because im beginner.
What you're passing for command (i.e. [convertBGR2HSV()]) doesn't make any sense. Think about what it's doing: calling the function convertBGR2HSV and putting its return value in a list, which is then used as command.
command is the function that you want to be called when the button is pressed, so that the code in it is run at that time. So, it doesn't make sense for you to call it yourself. Instead you just need to pass the function, e.g.
btn = Button(gui, text='Select A Image', width=15,height=3, bd='5', command=convertBGR2HSV)
If you want to do multiple things when the button is pressed, then write a function that does that and pass that as command, e.g.
def do_several_things():
do_thing_1()
do_thing_2()
do_thing_3()
...
button = Button(..., command=do_several_things)

Error object has no attribute in Paint app

This is the code, I got it from here https://www.youtube.com/watch?v=uW-NLL9dlBs
After many attempts, I solved some issues, but I still couldnt get it to work.
Its supposed to be an app for painting. I wanted it to have very large pixels with invisible grid too, so painting in it would create low resolution pixel art, similar to this. I dont know how to do that, as I couldnt find it anywhere. pixel image
from tkinter import *
from tkinter.ttk import Scale
from tkinter import colorchooser,filedialog,messagebox
import PIL.ImageGrab as ImageGrab
class Paint():
def __init__(self,root):
self.root = root
self.root.title("Paint")
self.root.geometry("800x520")
self.root.configure(background='white')
self.root.resizable(0,0)
self.pen_color = "black"
self.eraser_color = "white"
self.color_frame = LabelFrame(self.root,text='Color',font = ('arial',15),bd=5,relief=RIDGE,bg='white')
self.color_frame.place(x=0,y=0,width=70,height=185)
colors = ['#ff0000','#ff4dd2','#ffff33','#000000','#0066ff','#660033','#4dff4d','#b300b3','#00ffff','#808080','#99ffcc','#336600','#ff9966','#ff99ff','#00cc99']
i=j=0
for color in colors:
Button(self.color_frame,bg=color,bd=2,relief=RIDGE,width=3,command=lambda col =color:self.select_color(col)).grid(row=i,column=j)
i+=1
if i==6:
i=0
j=1
self.eraser_button = Button(self.root,text="ERASER",bd=4,bg='white',command=self.eraser,width=8,relief=RIDGE)
self.eraser_button.place(x=0,y=187)
self.clear_button = Button(self.root, text="Clear",bd=4,bg='white',command=lambda : self.canvas.delete("all"),width=8,relief=RIDGE)
self.clear_button.place(x=0,y=217)
self.save_button = Button(self.root,text="Save",bd=4,bg='white',command=self.save_paint,width=8,relief=RIDGE)
self.save_button.place(x=0,y=247)
self.canvas_color_button = Button(self.root,text="Canvas", bd=4 , bg='white', command=self.canvas_color(),width=8,relief=RIDGE)
self.canvas_color_button.place(x=0, y=277)
self.pen_size_scale_frame = LabelFrame(self.root,text="size",bd=5,bg='white',font=('arial',15,'bold'),relief=RIDGE)
self.pen_size_scale_frame.place(x=0,y=310,height=200,width=70)
self.pen_size = Scale(self.pen_size_scale_frame,orient=VERTICAL,from_ = 50, to = 0,length=170)
self.pen_size.set(1)
self.pen_size.grid(row=0,column=1,padx=15)
self.canvas = Canvas(self.root,bg='white',bd=5,relief=GROOVE,height=500,width=700)
self.canvas.place(x=80,y=0)
self.canvas.bind("<B1-Motion>",self.paint)
def paint(self,event):
x1,y1 = (event.x-2),(event.y-2)
x2,y2 = (event.x + 2),(event.y + 2)
self.canvas.create_oval(x1,y1,x2,y2,fill=self.pen_color,outline=self.pen_color,width=self.pen_size.get())
def select_color(self,col):
self.pen_color = self.eraser_color
def eraser(self):
self.pen_color = "white"
def canvas_color(self):
color = colorchooser.askcolor()
self.canvas.configure(background=color[1])
self.eraser_color = color[1]
def save_paint(self):
try:
filename = asksaveasfilename(defaultextension='.jpg')
x = self.root.winfo_rooty() + self.canvas.winfo_x()
y = self.root.winfo_rooty() + self.canvas.winfo_y()
x1 = x + self.canvas.winfo_width()
y1 = y + self.canvas.winfo_height()
ImageGrab.grab().crop((x,y,x1,y1)).save(filename)
messagebox.showinfo('paint says','image is saved as ' + str(filename))
except:
messagebox.showerror("paint says","unable to save image ,\n something went wrong")
if __name__ == "__main__":
root = Tk()
p = Paint(root)
root.mainloop()
In order to get your paint program working, the following bugs need to be addressed.
The self.canvas_color_button command has a bug. Just remove the parens to make it work.
There's a problem with color selection methods.
Here is the solution.
def select_color(self,col):
self.pen_color = col
def eraser(self):
self.pen_color = self.eraser_color
When saving a drawing, the image is not cropped correctly due to other widgets.
self.color_frame has a width of 70.
Your canvas is defined with a borderwidth(5) and a highlightthickness(2).
These values must be taken into account.
Here is one solution to crop your saved images correctly.
xoffset = self.color_frame.winfo_width()
yoffset = int(self.canvas["borderwidth"]) + int(self.canvas["highlightthickness"])
x = self.root.winfo_rooty() + self.canvas.winfo_x()
y = self.root.winfo_rooty() + self.canvas.winfo_y() + yoffset
x1 = x + self.canvas.winfo_width() - xoffset
y1 = y + self.canvas.winfo_height() - (yoffset * 2)

Python-3, my program doesn't show a negative image

So I need to follow the function in my textbook, to make an image negative and show the negative image. I've tried changing a few things in to replicate the previous function see to if that would change anything like typing in what image I want to have a negative of. It compiles and runs fine showing no errors it just doesn't show me a negative of my image, so I don't know whats the issue.
from cImage import *
def negativePixel(oldPixel):
newRed = 255 - oldPixel.getRed()
newGreen = 255 - oldPixel.getGreen()
newBlue = 255 - oldPixel.getBlue()
newPixel = Pixel(newRed, newGreen, newBlue)
return newPixel`
def MakeNegative(imageFile):
oldImage = FileImage(imageFile)
width = oldImage.getWidth()
height = oldImage.getHeight()
myImageWindow = ImageWin("Negative Image", width * 2, height)
oldImage.draw(myImageWindow)
newIn = EmptyImage(width, height)
for row in range(height):
for col in range(width):
oldPixel = oldImage.getPixel(col, row)
newPixel = negativePixel(oldPixel)
newIn.setPixel(col, row, newPixel)
newIn.setPosition(width + 1, 0)
newIn.draw(myImageWindow)
myImageWindow.exitOnClick()
Your code wasn't compiling or running for me; I fixed a few things - indentation, import image (not cImage), not invoking MakeNegative(), parameters out of order, etc. This works for me. I'm on Ubuntu 18.04, Python 3.6.9, cImage-2.0.2, Pillow-7.2.0.
from image import *
def negativePixel(oldPixel):
newRed = 255 - oldPixel.getRed()
newGreen = 255 - oldPixel.getGreen()
newBlue = 255 - oldPixel.getBlue()
newPixel = Pixel(newRed, newGreen, newBlue)
return newPixel
def MakeNegative(imageFile):
oldImage = FileImage(imageFile)
width = oldImage.getWidth()
height = oldImage.getHeight()
myImageWindow = ImageWin(width * 2, height, "Negative Image")
oldImage.draw(myImageWindow)
newIn = EmptyImage(width, height)
for row in range(height):
for col in range(width):
oldPixel = oldImage.getPixel(col, row)
newPixel = negativePixel(oldPixel)
newIn.setPixel(col, row, newPixel)
newIn.setPosition(width + 1, 0)
newIn.draw(myImageWindow)
myImageWindow.exitOnClick()
MakeNegative('Lenna_test_image.png')

Remove all empty space from image

I need to remove all white-spaces from image but I don't know how to do it..
I am using trim functionality to trim white spaces from border but still white-spaces are present in middle of image I am attaching my original image from which I want to remove white-spaces
my code
from PIL import Image, ImageChops
import numpy
def trim(im):
bg = Image.new(im.mode, im.size, im.getpixel((0, 0)))
diff = ImageChops.difference(im, bg)
diff = ImageChops.add(diff, diff, 2.0, -100)
box = diff.getbbox()
if box:
im.crop(box).save("trim_pil.png")
im = Image.open("/home/einfochips/Documents/imagecomparsion/kroger_image_comparison/SnapshotImages/screenshot_Hide.png")
im = trim(im)
but this code only remove space from borders, I need to remove spaces from middle also. Please help if possible, it would be very good if I got all five images in different PNG file.
You could go the long way with a for loop
from PIL import Image, ImageChops
def getbox(im, color):
bg = Image.new(im.mode, im.size, color)
diff = ImageChops.difference(im, bg)
diff = ImageChops.add(diff, diff, 2.0, -100)
return diff.getbbox()
def split(im):
retur = []
emptyColor = im.getpixel((0, 0))
box = getbox(im, emptyColor)
width, height = im.size
pixels = im.getdata()
sub_start = 0
sub_width = 0
offset = box[1] * width
for x in range(width):
if pixels[x + offset] == emptyColor:
if sub_width > 0:
retur.append((sub_start, box[1], sub_width, box[3]))
sub_width = 0
sub_start = x + 1
else:
sub_width = x + 1
if sub_width > 0:
retur.append((sub_start, box[1], sub_width, box[3]))
return retur
This makes it easy to retrieve the crop boxes in the image like this:
im = Image.open("/home/einfochips/Documents/imagecomparsion/kroger_image_comparison/SnapshotImages/screenshot_Hide.png")
for idx, box in enumerate(split(im)):
im.crop(box).save("trim_{0}.png".format(idx))
If you already know the size of the images toy want to extract you could go with
def split(im, box):
retur = []
pixels = im.getdata()
emptyColor = pixels[0]
width, height = im.size;
y = 0;
while y < height - box[3]:
x = 0
y_step = 1
while x < width - box[2]:
x_step = 1
if pixels[y*width + x] != emptyColor:
retur.append((x, y, box[2] + x, box[3] + y))
y_step = box[3] + 1
x_step = box[2] + 1
x += x_step
y += y_step
return retur
Adding another parameter to the call
for idx, box in enumerate(split(im, (0, 0, 365, 150))):
im.crop(box).save("trim_{0}.png".format(idx))

image tiling in loops using Python OpenCV

Python noob needs some help guys! Can someone show me how to rewrite my code using loops? Tried some different syntaxes but did not seem to work!
img = cv2.imread("C://Users//user//Desktop//research//images//Underwater_Caustics//set1//set1_color_0001.png")
tile11=img[1:640, 1:360]
cv2.imwrite('tile11_underwater_caustic_set1_0001.png', tile11)
tile12=img[641:1280, 1:360]
cv2.imwrite('tile12_underwater_caustic_set1_0001.png', tile12)
tile13=img[1281:1920, 1:360]
cv2.imwrite('tile13_underwater_caustic_set1_0001.png', tile13)
tile21=img[1:640, 361:720]
cv2.imwrite('tile21_underwater_caustic_set1_0001.png', tile21)
tile22=img[641:1280, 361:720]
cv2.imwrite('tile22_underwater_caustic_set1_0001.png', tile22)
tile23=img[1281:1920, 361:720]
cv2.imwrite('tile23_underwater_caustic_set1_0001.png', tile23)
tile31=img[1:640, 721:1080]
cv2.imwrite('tile31_underwater_caustic_set1_0001.png', tile31)
tile32=img[641:1280, 721:1080]
cv2.imwrite('tile32_underwater_caustic_set1_0001.png', tile32)
tile33=img[1281:1920, 721:1080]
cv2.imwrite('tile33_underwater_caustic_set1_0001.png', tile33)
As you can see, the image will be cut into 9 equal-size pieces, how to write it using loops?
This won't produce the same result like your code, but will give you some ideas:
img = cv2.imread('sample.jpg')
numrows, numcols = 4, 4
height = int(img.shape[0] / numrows)
width = int(img.shape[1] / numcols)
for row in range(numrows):
for col in range(numcols):
y0 = row * height
y1 = y0 + height
x0 = col * width
x1 = x0 + width
cv2.imwrite('tile_%d%d.jpg' % (row, col), img[y0:y1, x0:x1])
I needed image tiling where last parts or edge tiles are required to be full tile images.
Here is the code I use:
import cv2
import math
import os
Path = "FullImage.tif";
filename, file_extension = os.path.splitext(Path)
image = cv2.imread(Path, 0)
tileSizeX = 256;
tileSizeY = 256;
numTilesX = math.ceil(image.shape[1]/tileSizeX)
numTilesY = math.ceil(image.shape[0]/tileSizeY)
makeLastPartFull = True; # in case you need even siez
for nTileX in range(numTilesX):
for nTileY in range(numTilesY):
startX = nTileX*tileSizeX
endX = startX + tileSizeX
startY = nTileY*tileSizeY
endY = startY + tileSizeY;
if(endY > image.shape[0]):
endY = image.shape[0]
if(endX > image.shape[1]):
endX = image.shape[1]
if( makeLastPartFull == True and (nTileX == numTilesX-1 or nTileY == numTilesY-1) ):
startX = endX - tileSizeX
startY = endY - tileSizeY
currentTile = image[startY:endY, startX:endX]
cv2.imwrite(filename + '_%d_%d' % (nTileY, nTileX) + file_extension, currentTile)
This is for massive image reconstruction using part of flowfree his code. By using a folder of sliced images in the same area the script is, you can rebuild the image. I hope this helps.
import cv2
import glob
import os
dir = "."
pathname = os.path.join(dir, "*" + ".png")
images = [cv2.imread(img) for img in glob.glob(pathname)]
img = images[0]
numrows, numcols = 1,1
height = int(img.shape[0] / numrows)
width = int(img.shape[1] / numcols)
for row in range(numrows):
for col in range(numcols):
y0 = row * height
y1 = y0 + height
x0 = col * width
x1 = x0 + width
cv2.imwrite('merged_img_%d%d.jpg' % (row, col), img[y0:y1, x0:x1])

Categories