Skip to content

Commit

Permalink
Implement detection
Browse files Browse the repository at this point in the history
  • Loading branch information
JojiJoseph committed Nov 22, 2021
1 parent 3f900c8 commit 296afde
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,25 @@
Convert OpenCV aruco dictionaries to custom dictionaries
```bash
python3 convert_dicts.py
```
```
Then run test program
```bash
python3 aruco.py
```

## How It Works?

- First, detect edges using adaptive threshold and extract corners
- Then, convert corners to polygons using Douglas–Peucker algorithm
- Extract patches enclosed by 4 corner polygons, and remap each patch to a rectange
- For each such rectangle patch, divide it to grid and assign bits to each cell
- For each bitmap, check if it is in aruco marker dictionary. Consider the pattern valid if it is present in the dictionary

## Sample Output
Input Image

![Input image](test_image.jpg)

Output Image

![Output image](output_image.jpg)
67 changes: 67 additions & 0 deletions aruco.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import cv2
import pickle
import os
import numpy as np


class Aruco:
def __init__(self, dict_name="DICT_ARUCO_ORIGINAL") -> None:
self.dict_name = dict_name
with open(os.path.join("./dict", self.dict_name + ".pickle"), "rb") as f:
self.marker_size, self.n_markers, self.dict = pickle.load(f)

def detect(self, img_gray):
# Will return an array of (id, corners)

# Create edge image using adaptive threshold
img_thresh = cv2.adaptiveThreshold(
img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 0)
contours, _ = cv2.findContours(
img_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
candidate_rects = []

for cnt in contours:
cnt = cv2.approxPolyDP(cnt, epsilon=5, closed=True)
# Detect rectange of decent size
if len(cnt) == 4 and cv2.contourArea(cnt) > 200:
candidate_rects.append(cnt)

aruco_coords = np.array([[[40, 0]], [[0, 0]], [[0, 40]], [[40, 40]]])

result = []

for rect in candidate_rects:
h, status = cv2.findHomography(rect, aruco_coords)
img_out = cv2.warpPerspective(img_gray, h, dsize=(40, 40))
img_out = cv2.resize(img_out, (self.marker_size, self.marker_size))
ret, img_out = cv2.threshold(img_out, 127, 255, cv2.THRESH_BINARY)
img_out //= 255

# If it is valid then add it to results
if tuple(img_out.ravel().tolist()) in self.dict:
result.append(
[self.dict[tuple(img_out.ravel())][0],
rect]
)
return result


if __name__ == "__main__":
import time
img = cv2.imread("./test_image.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
aruco = Aruco("DICT_6X6_250")
start = time.time()
out = aruco.detect(img_gray)
end = time.time()
print(end-start)

img_out = img.copy()
for id, corners in out:
x, y = np.mean(corners.squeeze(), axis=0).astype(int)
cv2.polylines(img_out, [corners], True, (255,0,0), thickness=2)
img_out = cv2.drawMarker(img_out, (x, y), (0, 0, 255), thickness=2)
cv2.imshow("Input", img)
cv2.imshow("Output", img_out)
cv2.imwrite("./output_image.jpg", img_out)
cv2.waitKey()
Binary file added output_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 296afde

Please sign in to comment.