如何在图像上画一条线并检索线下的像素?
How to draw a line on image and retrieve pixels beneath the line?
我正在尝试在图像上画一条线并检索落在该线下方的所有像素值。我已经尝试过一种方法,您可以在其中检索 2 个鼠标单击坐标并计算两个鼠标坐标之间的斜率,但这种方法非常具体地只提取一行。如何更改线条的宽度并检索其下方的像素?我是 python 的新手,我不知道从哪里开始。任何想法或任何建议都将非常感谢。
简单理解我想在图像上画一条线并提取线下方的像素,并且当我们改变线的宽度时我也想提取扩展的像素值。我该怎么做?
from tkinter import *
import PIL
import PIL.Image
import PIL.ImageTk
root = Tk()
#setting up a tkinter canvas with scrollbars
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscroll = Scrollbar(frame, orient=HORIZONTAL)
xscroll.grid(row=1, column=0, sticky=E+W)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscroll.config(command=canvas.xview)
yscroll.config(command=canvas.yview)
frame.pack(fill=BOTH,expand=1)
#adding the image in the below line u16 us my image array.
img = PIL.ImageTk.PhotoImage(image =PIL.Image.fromarray(u16))
canvas.create_image(0,0,image=img,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL))
#function to be called when mouse is clicked
def printcoords(event):
#outputting x and y coords to console
click = event.x, event.y
print (click)
def printcoords_up(event):
#outputting x and y coords to console
rem_click=event.x, event.y
print (rem_click)
#mouseclick event
canvas.bind("<ButtonPress-1>",printcoords)
# canvas.bind("<ButtonMotion-1>", printcoords)
canvas.bind("<ButtonRelease-1>", printcoords_up )
root.mainloop()
##################编辑代码#####################
import tkinter
import numpy as np
import cv2
import sys
import PIL
import PIL.Image
import PIL.ImageTk as imtk
if "Tkinter" not in sys.modules:
from tkinter import *
curPth = sys.path[0]
###### u16 is my image array.
im = u16
tmpPth = curPth+'/temp.png'
ev = None
def click(event, back):
global ev, im
if ev == None:
ev = event
return None
# im = imgPth
# mask = cv2.cvtColor(im.copy()*0, cv2.COLOR_BGR2GRAY)
cv2.line(im, pt1=(ev.x, ev.y), pt2=(event.x, event.y), color=(255, 0, 0), thickness=40)
mask = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)[1]
out = im.copy()
out[np.where(mask == 0)] = 255
cv2.imwrite(tmpPth, out)
back.config(file=tmpPth)
print(event)
ev = event
window = tkinter.Tk()
back = imtk.PhotoImage(image =PIL.Image.fromarray(im))
my_label=Label(window, image=back)
my_label.place(x=0, y=0)
window.bind('<Button-1>', lambda event: click(event, back))
window.mainloop()
我对你的问题有点困惑;但是我想如果我误解了这个问题;它可能会在以后帮助其他人。我尝试用 @Dan Mašek 方法对其进行测试。
from tkinter import *
import numpy as np
import cv2
import sys
import PIL.Image as imge
import PIL.ImageTk as imtk
curPth = sys.path[0]
imgPth = curPth+'/back.png'
tmpPth = curPth+'/temp.png'
ev = None
thikness = 40
def click(event):
global ev, back, lbl
if ev == None:
ev = event
return None
im = cv2.imread(imgPth)
mask = cv2.cvtColor(im.copy()*0, cv2.COLOR_BGR2GRAY)
cv2.line(mask, pt1=(ev.x, ev.y), pt2=(event.x, event.y),
color=(255, 0, 0), thickness=thikness)
mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
out = im.copy()
out[np.where(mask == 0)] = 255
out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)
back = imtk.PhotoImage(image=imge.fromarray(out))
lbl.config(image=back)
# print(mask[np.where(mask == 255)])
x, X = min(ev.x, event.x)-thikness//2, max(ev.x, event.x)+thikness//2
y, Y = min(ev.y, event.y)-thikness//2, max(ev.y, event.y)+thikness//2
cropped = mask[y:Y, x:X]
print(cropped, cropped.shape)
cv2.imwrite(curPth+'/2d_line_area.png', cropped)
ev = event
root = Tk()
back = PhotoImage(file=imgPth)
lbl = Label(root, image=back)
lbl.place(x=0, y=0)
root.bind('<Button-1>', lambda event: click(event))
root.mainloop()
我用paint.net画的测试图:
Tkinter 主循环:
点击屏幕上的 2 个点后:
还有更多测试:
二维数组仅来自画线的区域。
更多示例:
x, X = min(ev.x, event.x)-thikness//2, max(ev.x, event.x)+thikness//2
y, Y = min(ev.y, event.y)-thikness//2, max(ev.y, event.y)+thikness//2
cropped1 = mask[y:Y, x:X]
cropped2 = out[y:Y, x:X]
print(cropped1, cropped1.shape)
cropped1=cv2.cvtColor(cropped1,cv2.COLOR_GRAY2RGB)
cropped2=cv2.cvtColor(cropped2,cv2.COLOR_BGR2RGB)
cv2.imwrite(curPth+'/2d_line_area.png', np.hstack((cropped1,cropped2)))
ev = event
我正在尝试在图像上画一条线并检索落在该线下方的所有像素值。我已经尝试过一种方法,您可以在其中检索 2 个鼠标单击坐标并计算两个鼠标坐标之间的斜率,但这种方法非常具体地只提取一行。如何更改线条的宽度并检索其下方的像素?我是 python 的新手,我不知道从哪里开始。任何想法或任何建议都将非常感谢。
简单理解我想在图像上画一条线并提取线下方的像素,并且当我们改变线的宽度时我也想提取扩展的像素值。我该怎么做?
from tkinter import *
import PIL
import PIL.Image
import PIL.ImageTk
root = Tk()
#setting up a tkinter canvas with scrollbars
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscroll = Scrollbar(frame, orient=HORIZONTAL)
xscroll.grid(row=1, column=0, sticky=E+W)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscroll.config(command=canvas.xview)
yscroll.config(command=canvas.yview)
frame.pack(fill=BOTH,expand=1)
#adding the image in the below line u16 us my image array.
img = PIL.ImageTk.PhotoImage(image =PIL.Image.fromarray(u16))
canvas.create_image(0,0,image=img,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL))
#function to be called when mouse is clicked
def printcoords(event):
#outputting x and y coords to console
click = event.x, event.y
print (click)
def printcoords_up(event):
#outputting x and y coords to console
rem_click=event.x, event.y
print (rem_click)
#mouseclick event
canvas.bind("<ButtonPress-1>",printcoords)
# canvas.bind("<ButtonMotion-1>", printcoords)
canvas.bind("<ButtonRelease-1>", printcoords_up )
root.mainloop()
##################编辑代码#####################
import tkinter
import numpy as np
import cv2
import sys
import PIL
import PIL.Image
import PIL.ImageTk as imtk
if "Tkinter" not in sys.modules:
from tkinter import *
curPth = sys.path[0]
###### u16 is my image array.
im = u16
tmpPth = curPth+'/temp.png'
ev = None
def click(event, back):
global ev, im
if ev == None:
ev = event
return None
# im = imgPth
# mask = cv2.cvtColor(im.copy()*0, cv2.COLOR_BGR2GRAY)
cv2.line(im, pt1=(ev.x, ev.y), pt2=(event.x, event.y), color=(255, 0, 0), thickness=40)
mask = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)[1]
out = im.copy()
out[np.where(mask == 0)] = 255
cv2.imwrite(tmpPth, out)
back.config(file=tmpPth)
print(event)
ev = event
window = tkinter.Tk()
back = imtk.PhotoImage(image =PIL.Image.fromarray(im))
my_label=Label(window, image=back)
my_label.place(x=0, y=0)
window.bind('<Button-1>', lambda event: click(event, back))
window.mainloop()
我对你的问题有点困惑;但是我想如果我误解了这个问题;它可能会在以后帮助其他人。我尝试用 @Dan Mašek 方法对其进行测试。
from tkinter import *
import numpy as np
import cv2
import sys
import PIL.Image as imge
import PIL.ImageTk as imtk
curPth = sys.path[0]
imgPth = curPth+'/back.png'
tmpPth = curPth+'/temp.png'
ev = None
thikness = 40
def click(event):
global ev, back, lbl
if ev == None:
ev = event
return None
im = cv2.imread(imgPth)
mask = cv2.cvtColor(im.copy()*0, cv2.COLOR_BGR2GRAY)
cv2.line(mask, pt1=(ev.x, ev.y), pt2=(event.x, event.y),
color=(255, 0, 0), thickness=thikness)
mask = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
out = im.copy()
out[np.where(mask == 0)] = 255
out = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)
back = imtk.PhotoImage(image=imge.fromarray(out))
lbl.config(image=back)
# print(mask[np.where(mask == 255)])
x, X = min(ev.x, event.x)-thikness//2, max(ev.x, event.x)+thikness//2
y, Y = min(ev.y, event.y)-thikness//2, max(ev.y, event.y)+thikness//2
cropped = mask[y:Y, x:X]
print(cropped, cropped.shape)
cv2.imwrite(curPth+'/2d_line_area.png', cropped)
ev = event
root = Tk()
back = PhotoImage(file=imgPth)
lbl = Label(root, image=back)
lbl.place(x=0, y=0)
root.bind('<Button-1>', lambda event: click(event))
root.mainloop()
我用paint.net画的测试图:
Tkinter 主循环:
点击屏幕上的 2 个点后:
还有更多测试:
二维数组仅来自画线的区域。
更多示例:
x, X = min(ev.x, event.x)-thikness//2, max(ev.x, event.x)+thikness//2
y, Y = min(ev.y, event.y)-thikness//2, max(ev.y, event.y)+thikness//2
cropped1 = mask[y:Y, x:X]
cropped2 = out[y:Y, x:X]
print(cropped1, cropped1.shape)
cropped1=cv2.cvtColor(cropped1,cv2.COLOR_GRAY2RGB)
cropped2=cv2.cvtColor(cropped2,cv2.COLOR_BGR2RGB)
cv2.imwrite(curPth+'/2d_line_area.png', np.hstack((cropped1,cropped2)))
ev = event