main.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import time
  2. import cv2
  3. import numpy as np
  4. import numpy as np
  5. import pygame
  6. import pygame.gfxdraw
  7. import pygame as pg
  8. from random import randrange
  9. import pymunk.pygame_util
  10. def lower_update(value):
  11. global lower
  12. lower = value
  13. def upper_update(value):
  14. global upper
  15. upper = value
  16. def find_paper_and_crop(thres):
  17. global pp_rect, pp_dst, maxW, maxH
  18. contours, _ = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  19. largest_contour = max(contours, key=cv2.contourArea)
  20. epsilon = 0.02 * cv2.arcLength(largest_contour, True)
  21. approx = cv2.approxPolyDP(largest_contour, epsilon, True)
  22. if len(approx) == 4:
  23. pts = approx.reshape(4, 2)
  24. rect = order_points(pts)
  25. (tl, tr, br, bl) = rect
  26. # print("Ordered points:", rect)
  27. widthA = np.linalg.norm(br - bl)
  28. widthB = np.linalg.norm(tr - tl)
  29. maxWidth = max(int(widthA), int(widthB))
  30. heightA = np.linalg.norm(tr - br)
  31. heightB = np.linalg.norm(tl - bl)
  32. maxHeight = max(int(heightA), int(heightB))
  33. dst = np.array(
  34. [
  35. [0, 0],
  36. [maxWidth, 0],
  37. [maxWidth, maxHeight],
  38. [0, maxHeight],
  39. ],
  40. dtype="float32",
  41. )
  42. pp_rect = rect
  43. pp_dst = dst
  44. maxW = maxWidth
  45. maxH = maxHeight
  46. warped = apply_perspective(thres, rect, dst, maxW, maxH)
  47. return warped
  48. else:
  49. raise Exception("Paper not detected or the paper does not have four corners")
  50. def apply_perspective(image, rect, ppd, maxW, maxH):
  51. M = cv2.getPerspectiveTransform(rect, ppd)
  52. return cv2.warpPerspective(image, M, (maxW, maxH))
  53. def order_points(pts):
  54. rect = np.zeros((4, 2), dtype="float32")
  55. s = pts.sum(axis=1)
  56. rect[0] = pts[np.argmin(s)]
  57. rect[2] = pts[np.argmax(s)]
  58. diff = np.diff(pts, axis=1)
  59. rect[1] = pts[np.argmin(diff)]
  60. rect[3] = pts[np.argmax(diff)]
  61. return rect
  62. def process_image(img):
  63. global pp_rect, pp_dst, maxW, maxH
  64. img = apply_perspective(img, pp_rect, pp_dst, maxW, maxH)
  65. img = cv2.resize(
  66. img,
  67. (0, 0),
  68. fx=1280 / img.shape[1],
  69. fy=800 / img.shape[0],
  70. interpolation=cv2.INTER_NEAREST_EXACT,
  71. )
  72. return img
  73. def create_ball(space):
  74. ball_moment = pymunk.moment_for_circle(ball_mass, 0, ball_radius)
  75. ball_body = pymunk.Body(ball_mass, ball_moment)
  76. ball_body.position = 500, 100
  77. ball_shape = pymunk.Circle(ball_body, ball_radius)
  78. ball_shape.elasticity = 1
  79. ball_shape.friction = 1
  80. space.add(ball_body, ball_shape)
  81. return ball_body
  82. def create_segment(from_, to_, thickness, space, color):
  83. segment_shape = pymunk.Segment(space.static_body, from_, to_, thickness)
  84. segment_shape.color = pg.color.THECOLORS[color]
  85. space.add(segment_shape)
  86. def create_rect(x1, y1, x2, y2, x3, y3, x4, y4):
  87. # правый верх, левый верх, левый низ, левый верх
  88. color = "white"
  89. create_segment((x1, y1), (x2, y2), 3, space, color)
  90. create_segment((x2, y2), (x3, y3), 3, space, color)
  91. create_segment((x3, y3), (x4, y4), 3, space, color)
  92. create_segment((x4, y4), (x1, y1), 3, space, color)
  93. pymunk.pygame_util.positive_y_is_up = False
  94. # cv2.namedWindow("Image", cv2.WINDOW_GUI_NORMAL)
  95. cv2.namedWindow("Mask", cv2.WINDOW_GUI_NORMAL)
  96. cap = cv2.VideoCapture(0)
  97. cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 1)
  98. cap.set(cv2.CAP_PROP_EXPOSURE, 5)
  99. lower = 0
  100. upper = 55
  101. cv2.createTrackbar("Lower", "Mask", lower, 255, lower_update)
  102. cv2.createTrackbar("Upper", "Mask", upper, 255, upper_update)
  103. pp_rect = []
  104. pp_dst = []
  105. maxW = 0
  106. maxH = 0
  107. img = cap.read()[1]
  108. # img = cv2.imread("cllean.jpg")
  109. img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  110. # img = cv2.threshold(img, 10, 255, type=cv2.THRESH_BINARY)[1]
  111. img = cv2.threshold(img, 70, 255, type=cv2.THRESH_BINARY)[1]
  112. cv2.imshow("b", img)
  113. # while True: cv2.waitKey(1)
  114. crop = find_paper_and_crop(img)
  115. # cv2.imshow("a", crop)
  116. crop = cv2.resize(
  117. crop,
  118. (0, 0),
  119. fx=1280 / crop.shape[1],
  120. fy=800 / crop.shape[0],
  121. interpolation=cv2.INTER_NEAREST_EXACT,
  122. )
  123. RES = WIDTH, HEIGHT = 1280, 800
  124. FPS = 60
  125. surface = pg.display.set_mode((0, 0), pygame.FULLSCREEN, display=1)
  126. # print(pg.display.get_desktop_sizes())
  127. clock = pg.time.Clock()
  128. draw_options = pymunk.pygame_util.DrawOptions(surface)
  129. space = pymunk.Space()
  130. space.gravity = 0, 1000
  131. ball_mass, ball_radius = 1000000, 10
  132. balls = [([randrange(256) for i in range(3)], create_ball(space)) for j in range(0)]
  133. while True:
  134. # bts = socket.recv()
  135. surface.fill(pg.Color("white"))
  136. space.step(1 / FPS)
  137. space.debug_draw(draw_options)
  138. for color, ball in balls:
  139. if (
  140. ball.position.x < -ball_radius
  141. or ball.position.x > WIDTH + ball_radius
  142. or ball.position.y < -ball_radius
  143. or ball.position.y > HEIGHT + ball_radius
  144. ):
  145. ball.position = 500, 100
  146. ball.velocity = (0, 0)
  147. pg.display.flip()
  148. clock.tick(FPS)
  149. # cv2.imshow("Image", frame2)
  150. for event in pygame.event.get():
  151. if event.type == pygame.KEYDOWN and event.key == pygame.K_e:
  152. space.remove(*space.shapes)
  153. surface.fill("white")
  154. pygame.display.flip()
  155. time.sleep(0.5)
  156. aeae = cap.read()[1]
  157. balls = [
  158. ([randrange(256) for i in range(3)], create_ball(space))
  159. for j in range(100)
  160. ]
  161. # aeae = cv2.imread("cllean.jpg")
  162. aeae = process_image(aeae)
  163. # frame = aeae.copy()
  164. # frame2 = frame.copy()
  165. gray = aeae.copy()
  166. # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  167. gray = cv2.GaussianBlur(gray, (7, 7), 0)
  168. mask = cv2.Canny(gray, lower, upper)
  169. # cv2.imshow('Mask', mask)
  170. cnts, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  171. # for i in range(len(cnts)):
  172. # cv2.drawContours(frame2, cnts, i, (0, 0, 0), 1)
  173. for index, cnt in enumerate(cnts):
  174. rect = cv2.minAreaRect(cnt)
  175. box = cv2.boxPoints(rect)
  176. box = np.int0(box)
  177. # cv2.drawContours(frame2, [box], 0, (0, 0, 255), 2)
  178. create_rect(*[a for b in box for a in b])
  179. if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
  180. cv2.destroyAllWindows()
  181. exit()