|  | @@ -0,0 +1,229 @@
 | 
	
		
			
				|  |  | +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 = "green"
 | 
	
		
			
				|  |  | +    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(2)
 | 
	
		
			
				|  |  | +# 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, 10, 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)
 | 
	
		
			
				|  |  | +            balls = [
 | 
	
		
			
				|  |  | +                ([randrange(256) for i in range(3)], create_ball(space))
 | 
	
		
			
				|  |  | +                for j in range(100)
 | 
	
		
			
				|  |  | +            ]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            # aeae = cap.read()[1]
 | 
	
		
			
				|  |  | +            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()
 |