123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- import time
- import cv2
- import numpy as np
- import numpy as np
- import pygame
- import pygame.gfxdraw
- import pygame as pg
- from random import randrange
- import pymunk.pygame_util
- def lower_update(value):
- global lower
- lower = value
- def upper_update(value):
- global upper
- upper = value
- def find_paper_and_crop(thres):
- global pp_rect, pp_dst, maxW, maxH
- contours, _ = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- largest_contour = max(contours, key=cv2.contourArea)
- epsilon = 0.02 * cv2.arcLength(largest_contour, True)
- approx = cv2.approxPolyDP(largest_contour, epsilon, True)
- if len(approx) == 4:
- pts = approx.reshape(4, 2)
- rect = order_points(pts)
- (tl, tr, br, bl) = rect
- # print("Ordered points:", rect)
- widthA = np.linalg.norm(br - bl)
- widthB = np.linalg.norm(tr - tl)
- maxWidth = max(int(widthA), int(widthB))
- heightA = np.linalg.norm(tr - br)
- heightB = np.linalg.norm(tl - bl)
- maxHeight = max(int(heightA), int(heightB))
- dst = np.array(
- [
- [0, 0],
- [maxWidth, 0],
- [maxWidth, maxHeight],
- [0, maxHeight],
- ],
- dtype="float32",
- )
- pp_rect = rect
- pp_dst = dst
- maxW = maxWidth
- maxH = maxHeight
- warped = apply_perspective(thres, rect, dst, maxW, maxH)
- return warped
- else:
- raise Exception("Paper not detected or the paper does not have four corners")
- def apply_perspective(image, rect, ppd, maxW, maxH):
- M = cv2.getPerspectiveTransform(rect, ppd)
- return cv2.warpPerspective(image, M, (maxW, maxH))
- def order_points(pts):
- rect = np.zeros((4, 2), dtype="float32")
- s = pts.sum(axis=1)
- rect[0] = pts[np.argmin(s)]
- rect[2] = pts[np.argmax(s)]
- diff = np.diff(pts, axis=1)
- rect[1] = pts[np.argmin(diff)]
- rect[3] = pts[np.argmax(diff)]
- return rect
- def process_image(img):
- global pp_rect, pp_dst, maxW, maxH
- img = apply_perspective(img, pp_rect, pp_dst, maxW, maxH)
- img = cv2.resize(
- img,
- (0, 0),
- fx=1280 / img.shape[1],
- fy=800 / img.shape[0],
- interpolation=cv2.INTER_NEAREST_EXACT,
- )
- return img
- def create_ball(space):
- ball_moment = pymunk.moment_for_circle(ball_mass, 0, ball_radius)
- ball_body = pymunk.Body(ball_mass, ball_moment)
- ball_body.position = 500, 100
- ball_shape = pymunk.Circle(ball_body, ball_radius)
- ball_shape.elasticity = 1
- ball_shape.friction = 1
- space.add(ball_body, ball_shape)
- return ball_body
- def create_segment(from_, to_, thickness, space, color):
- segment_shape = pymunk.Segment(space.static_body, from_, to_, thickness)
- segment_shape.color = pg.color.THECOLORS[color]
- space.add(segment_shape)
- def create_rect(x1, y1, x2, y2, x3, y3, x4, y4):
- # правый верх, левый верх, левый низ, левый верх
- color = "white"
- create_segment((x1, y1), (x2, y2), 3, space, color)
- create_segment((x2, y2), (x3, y3), 3, space, color)
- create_segment((x3, y3), (x4, y4), 3, space, color)
- create_segment((x4, y4), (x1, y1), 3, space, color)
- pymunk.pygame_util.positive_y_is_up = False
- # cv2.namedWindow("Image", cv2.WINDOW_GUI_NORMAL)
- cv2.namedWindow("Mask", cv2.WINDOW_GUI_NORMAL)
- cap = cv2.VideoCapture(0)
- cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 1)
- cap.set(cv2.CAP_PROP_EXPOSURE, 5)
- lower = 0
- upper = 55
- cv2.createTrackbar("Lower", "Mask", lower, 255, lower_update)
- cv2.createTrackbar("Upper", "Mask", upper, 255, upper_update)
- pp_rect = []
- pp_dst = []
- maxW = 0
- maxH = 0
- img = cap.read()[1]
- # img = cv2.imread("cllean.jpg")
- img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- # img = cv2.threshold(img, 10, 255, type=cv2.THRESH_BINARY)[1]
- img = cv2.threshold(img, 70, 255, type=cv2.THRESH_BINARY)[1]
- cv2.imshow("b", img)
- # while True: cv2.waitKey(1)
- crop = find_paper_and_crop(img)
- # cv2.imshow("a", crop)
- crop = cv2.resize(
- crop,
- (0, 0),
- fx=1280 / crop.shape[1],
- fy=800 / crop.shape[0],
- interpolation=cv2.INTER_NEAREST_EXACT,
- )
- RES = WIDTH, HEIGHT = 1280, 800
- FPS = 60
- surface = pg.display.set_mode((0, 0), pygame.FULLSCREEN, display=1)
- # print(pg.display.get_desktop_sizes())
- clock = pg.time.Clock()
- draw_options = pymunk.pygame_util.DrawOptions(surface)
- space = pymunk.Space()
- space.gravity = 0, 1000
- ball_mass, ball_radius = 1000000, 10
- balls = [([randrange(256) for i in range(3)], create_ball(space)) for j in range(0)]
- while True:
- # bts = socket.recv()
- surface.fill(pg.Color("white"))
- space.step(1 / FPS)
- space.debug_draw(draw_options)
- for color, ball in balls:
- if (
- ball.position.x < -ball_radius
- or ball.position.x > WIDTH + ball_radius
- or ball.position.y < -ball_radius
- or ball.position.y > HEIGHT + ball_radius
- ):
- ball.position = 500, 100
- ball.velocity = (0, 0)
- pg.display.flip()
- clock.tick(FPS)
- # cv2.imshow("Image", frame2)
- for event in pygame.event.get():
- if event.type == pygame.KEYDOWN and event.key == pygame.K_e:
- space.remove(*space.shapes)
- surface.fill("white")
- pygame.display.flip()
- time.sleep(0.5)
- aeae = cap.read()[1]
- balls = [
- ([randrange(256) for i in range(3)], create_ball(space))
- for j in range(100)
- ]
- # aeae = cv2.imread("cllean.jpg")
- aeae = process_image(aeae)
- # frame = aeae.copy()
- # frame2 = frame.copy()
- gray = aeae.copy()
- # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
- gray = cv2.GaussianBlur(gray, (7, 7), 0)
- mask = cv2.Canny(gray, lower, upper)
- # cv2.imshow('Mask', mask)
- cnts, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- # for i in range(len(cnts)):
- # cv2.drawContours(frame2, cnts, i, (0, 0, 0), 1)
- for index, cnt in enumerate(cnts):
- rect = cv2.minAreaRect(cnt)
- box = cv2.boxPoints(rect)
- box = np.int0(box)
- # cv2.drawContours(frame2, [box], 0, (0, 0, 255), 2)
- create_rect(*[a for b in box for a in b])
- if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
- cv2.destroyAllWindows()
- exit()
|