|
| 1 | +"""Projector-Camera with simple gray code |
| 2 | +""" |
| 3 | +import os |
| 4 | +import time |
| 5 | +import numpy as np |
| 6 | +import cv2 |
| 7 | +import structuredlight as sl # https://github.com/elerac/structuredlight |
| 8 | +from fullscreen import FullScreen |
| 9 | + |
| 10 | +def main(): |
| 11 | + # Output directory names |
| 12 | + OUTPUT_DIRNAME_BASE = "procam_capture" |
| 13 | + OUTPUT_DIRNAME_CODE = f"{OUTPUT_DIRNAME_BASE}/code" |
| 14 | + OUTPUT_DIRNAME_OBSERVE = f"{OUTPUT_DIRNAME_BASE}/observe" |
| 15 | + os.makedirs(OUTPUT_DIRNAME_CODE, exist_ok=True) |
| 16 | + os.makedirs(OUTPUT_DIRNAME_OBSERVE, exist_ok=True) |
| 17 | + |
| 18 | + # Cameta setup (use your USB camera) |
| 19 | + CAMERA_INDEX = 0 |
| 20 | + camera = cv2.VideoCapture(CAMERA_INDEX) |
| 21 | + |
| 22 | + # Projector setup |
| 23 | + projector = FullScreen() |
| 24 | + height, width = projector.shape[:2] |
| 25 | + |
| 26 | + # Generate gray code |
| 27 | + gray = sl.Gray() |
| 28 | + imlist_code = gray.generate((width, height)) |
| 29 | + |
| 30 | + # Projection and Capture |
| 31 | + imlist_observe = [] |
| 32 | + for i, img_code in enumerate(imlist_code): |
| 33 | + # Projection |
| 34 | + projector.imshow(img_code) |
| 35 | + time.sleep(0.2) |
| 36 | + |
| 37 | + # Capture |
| 38 | + ret, img_observe_bgr = camera.read() |
| 39 | + img_observe = cv2.cvtColor(img_observe_bgr, cv2.COLOR_BGR2GRAY) |
| 40 | + imlist_observe.append(img_observe) |
| 41 | + |
| 42 | + # Save images |
| 43 | + cv2.imwrite(f"{OUTPUT_DIRNAME_CODE}/code-{i+1}.png", img_code) |
| 44 | + cv2.imwrite(f"{OUTPUT_DIRNAME_OBSERVE}/observe-{i+1}.png", img_observe) |
| 45 | + |
| 46 | + # Decode gray code |
| 47 | + img_index = gray.decode(imlist_observe, thresh=127) |
| 48 | + |
| 49 | + # Save decoded result |
| 50 | + img_index_u8 = np.clip(img_index / width * 255.0, 0, 255).astype(np.uint8) |
| 51 | + cv2.imwrite(f"{OUTPUT_DIRNAME_BASE}/index.png", img_index_u8) |
| 52 | + |
| 53 | +if __name__=="__main__": |
| 54 | + main() |
0 commit comments