Creating a gui instead figure - python-3.x

First time posting here.
I need to create GUI that will upload video from my webcam and zoom in specific part of the video.
My code works for zooming but instead a Gui, it creates a figure.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import tkinter as tk
from tkinter import *
from tkinter import ttk
import cv2
boxSize = 150
enlargeBy = 3
def getBoxCoordinates(cap, size):
width = cap.get(3)
height = cap.get(4)
x1 = int(width / 2) - int(size / 2)
y1 = int(height / 2) - int(size / 2)
x2 = int(width / 2) + int(size / 2)
y2 = int(height / 2) + int(size / 2)
return [(x1, y1), (x2, y2)]
def getBox(cap, boxSize, frame, enlargeBy):
[(x1, y1), (x2, y2)] = getBoxCoordinates(cap, boxSize);
# Get pixels in box
box_img = frame[y1 + 1:y2, x1 + 1:x2] # +1 cuz it excludes initial
pixel interval
return cv2.resize(box_img, None, fx=enlargeBy, fy=enlargeBy,
interpolation=cv2.INTER_LINEAR) # different
interpolation methods
cap = cv2.VideoCapture(0);
ret, frame = cap.read()
figWidth = 20
figHeight = 8
fig = plt.Figure(figsize=(figWidth, figHeight))
enlarged = getBox(cap, boxSize, frame, enlargeBy)
[(x1, y1), (x2, y2)] = getBoxCoordinates(cap, boxSize);
#cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), lineType=1)
video_plot = plt.subplot2grid((figHeight, figWidth), (0, 0), colspan=4,
rowspan=4)
video_plot.axis('off')
video_plot.set_title("Camera feed")
video = video_plot.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
rectangle = plt.Rectangle((x1,y1), x2-x1, y2-y1, edgecolor="gold",
fill=False)
video_plot.add_patch(rectangle)
def updatefig(i):
ret, frame = cap.read()
video.set_data(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
return [video]
ani = animation.FuncAnimation(fig, updatefig, interval=20, frames=200,
blit=True)
plt.tight_layout()
plt.show()
cv2.destroyAllWindows()
plt.show()

Related

Slider is not updating my diagram correctly

I am trying to plot the biffurcation diagram and its equation.
My problem is that I want to put a slider for when I change the rate in the logistic map equation, but I can't seem to understand what I need to code in the update function.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
rate = np.linspace(1, 4, 1000)
N = 1000
x = np.zeros(N) + 0.5
count = np.arange(round(N*0.9), N)
y = np.zeros(N) + 0.5
#t = 1
# Biffurcation
for rs in range(len(rate)):
for n in range(N-1):
x[n+1] = rate[rs] * x[n] * (1-x[n])
u = np.unique(x[count])
r = rate[rs] * np.ones(len(u))
for i in range(N - 1):
y[i + 1] = rate[rs] * y[i] * (1 - y[i])
# plotting
plt.plot(r, u, '.', markersize=2)
plt.ylabel(ylabel='X')
plt.xlabel(xlabel='r')
plt.title('Biffurcation')
# Plotting
fig, ax = plt.subplots()
axes, = ax.plot(y, 'o-')
ax.set_ylabel(ylabel='X')
ax.set_xlabel(xlabel='Time')
ax.set_title('$x_{n+1}$ = r * $x_{n}$ * (1-$x_{n}$)')
# defining axSlider
fig.subplots_adjust(bottom=0.25)
ax_slider = fig.add_axes([0.15, 0.1, 0.65, 0.03])
slider = Slider(ax_slider, label='r', valmin=1, valmax=4, valinit=1, valstep=rate)
# updating the plot
def update(val):
current_v = slider.val
rate[rs] = current_v
axes.set_ydata(rate[rs])
fig.canvas.draw()
slider.on_changed(update)
plt.show()
I tried to update my plot for when I change the rate on my slider, but it is not working properly.
def update(val):
current_v = slider.val
rate[rs] = current_v
axes.set_ydata(rate[rs])
fig.canvas.draw()

Place and insert plane image along path using matplotlib

My code is a fair bit more advanced, but in simple terms I am looking to place and rotate an image of a plane along a path using matplotlib. Ideally I would be able to select the angle and how far along the path the image should be placed. Any ideas? My ideal output would be something like this (ignoring the coordinates I already fixed that in my real code).
Image of Norway used:
Code
import matplotlib.pyplot as plt
import matplotlib.image as img
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def x2map(x, x_scale):
return x * x_scale
def y2map(y, y_scale):
return (1 - y) * y_scale
if __name__ == "__main__":
image_url = "Norge2.png"
# Obtains the scaling for the figure
map = img.imread(image_url)
fig, ax = plt.subplots()
im = ax.imshow(map)
_, x_scale = plt.xlim()
y_scale, _ = plt.ylim()
# Fixes the axis to 0-1 and 0-1
positions_x = [i * x_scale / 10 for i in range(0, 11)]
positions_y = [i * y_scale / 10 for i in range(0, 11)]
labels = [i / 10 for i in range(0, 11)]
ax.set_xticks(positions_x)
ax.set_xticklabels([i / 10 for i in range(0, 11)])
ax.set_yticks(positions_y)
ax.set_yticklabels([(10 - i) / 10 for i in range(0, 11)])
route_color = "red"
route_ls = "-"
city_marker ="o"
city_color = "red"
A = [x2map(0.125,x_scale), y2map(0.14,y_scale)]
B = [x2map(0.772,x_scale), y2map(0.92,y_scale)]
plt.plot(
[A[0], B[0]], [A[1], B[1]], marker='o', color=route_color, ls=route_ls
)
plt.show()

OpenCV Python HoughLines Transformation get the rectangle points to crop the original image

Is there anyway to get the rectangle points from the HoughLines Transformation results and apply the crop point to original image to get the cropped image. I have copied the code form the documentation. The idea is to extract the document from an image. Below is the result from the HoughLines Transformation and I required the intersection point to crop the image.
"""
#file hough_lines.py
#brief This program demonstrates line finding with the Hough transform
"""
import sys
import math
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def main(argv=[]):
default_file = "/Users/apple/Downloads/Unknown-4"
filename = argv[0] if len(argv) > 0 else default_file
# Loads an image
src = cv.imread(cv.samples.findFile(filename), cv.IMREAD_GRAYSCALE)
# Check if image is loaded fine
if src is None:
print ('Error opening image!')
print ('Usage: hough_lines.py [image_name -- default ' + default_file + '] \n')
return -1
dst = cv.Canny(src, 50, 200, None, 3)
# Copy edges to the images that will display the results in BGR
cdst = cv.cvtColor(dst, cv.COLOR_GRAY2BGR)
cdstP = np.copy(cdst)
lines = cv.HoughLines(dst, 1, np.pi / 180, 150, None, 0, 0)
if lines is not None:
for i in range(0, len(lines)):
rho = lines[i][0][0]
theta = lines[i][0][1]
a = math.cos(theta)
b = math.sin(theta)
x0 = a * rho
y0 = b * rho
pt1 = (int(x0 + 1000*(-b)), int(y0 + 1000*(a)))
pt2 = (int(x0 - 1000*(-b)), int(y0 - 1000*(a)))
cv.line(cdst, pt1, pt2, (0,0,255), 3, cv.LINE_AA)
linesP = cv.HoughLinesP(dst, 1, np.pi / 180, 50, None, 50, 10)
if linesP is not None:
for i in range(0, len(linesP)):
l = linesP[i][0]
cv.line(cdstP, (l[0], l[1]), (l[2], l[3]), (0,0,255), 3, cv.LINE_AA)
#cv.imshow("Source", src)
#plt.imshow(src)
plt.imshow(cdstP)
#plt.imshow(cdstP)
if __name__ == "__main__":
main()

cv2.CascadeClassifier resizing image before prediction fails

I have a code that takes a video file and uses cv2.CascadeClassifier to draw a rectangle over the face. However, the initial video has frames sized 720*1280*3. So I want to resize them before predicting.
from skimage.transform import rescale
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
video_capture = cv2.VideoCapture('/Users/user/Desktop/300wv/001/vid.avi')
desired_squared_shape = 128
while True:
# Capture frame-by-frame
ret, frame = video_capture.read()
# resize whilst manintaing scale start
y, x, _ = frame.shape
val = max(x, y)
scaling_fac = desired_squared_shape / val
image_rescaled = rescale(frame, scaling_fac, anti_aliasing=False, multichannel=True)
y1, x1, _ = image_rescaled.shape
width_pad = int((desired_squared_shape - y1) / 2) # for both sides
height_pad = int((desired_squared_shape - x1) / 2)
image_rescaled = cv2.copyMakeBorder(image_rescaled,
width_pad,
(desired_squared_shape - y1) - width_pad,
height_pad,
(desired_squared_shape - x1) - height_pad, borderType=cv2.BORDER_CONSTANT)
image_rescaled = image_rescaled.astype(np.uint8)
# resize whilst maintaining scale end
gray = cv2.cvtColor(image_rescaled, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CV_HAAR_SCALE_IMAGE
)
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# Display the resulting frame
cv2.imshow('Video', image_rescaled)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()
If I comment out the section 'resize whilst maintaining scale' start to end and use frame to create gray it works but it won't work with resized image

drawing lines and distance to them on image opencv python

I encountered such a problem: I can not draw lines on the image where the color was determined, and also find out the distance to this place. Help to make it as in the image below:
My code:
import cv2
import numpy as np
from PIL import ImageGrab
while True:
screen = np.array(ImageGrab.grab(bbox=(0,40,800,640)))
rgb_screen = cv2.cvtColor(screen, cv2.COLOR_BGR2RGB)
lower = np.array([72, 160, 160])
upper = np.array([112, 249, 249])
mask = cv2.inRange(rgb_screen, lower, upper)
output = cv2.bitwise_and(rgb_screen, rgb_screen, mask=mask)
cv2.imshow('window', output)
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
I can't help much because I do not have your original image. But you could read my code and maybe get an idea. For distance I do not know what u mean, so I made an example on how to get distance of top left corner to bottom left. You can apply other points or apply it as ratio depanding on your demands.
import cv2
import numpy as np
img = cv2.imread('untitled.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray,150,255,cv2.THRESH_BINARY)
im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
area = sorted(contours, key=cv2.contourArea, reverse=True)
c = area[0]
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
print(box)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)
extreme_left = tuple(c[c[:, :, 0].argmin()][0])
extreme_top = tuple(c[c[:, :, 1].argmin()][0])
x1 = box[1,0]
y1 = box[1,1]
x2 = box[0,0]
y2 = box[0,1]
distance = np.sqrt( (x1 - x2)**2 + (y1 - y2)**2 )
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'Distance: '+str(distance),(1,300), font, 0.5,(255,255,255),2,cv2.LINE_AA)
cv2.circle(img, (x2,y2), 5, (255, 0, 0), -1)
cv2.circle(img, (x1,y1), 5, (255, 0, 0), -1)
cv2.imshow('image', img)

Resources