main.py 6.3 KB

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