├── README.md ├── flir ├── blend.py ├── camera_preview.py ├── canny1.py ├── canny2.py ├── canny3.py ├── canny4.py ├── flir_preview.py └── horizontal.py └── micro └── ocr_preview.py /README.md: -------------------------------------------------------------------------------- 1 | # Raspberry Pi User Group Meetup 19th 2 | 3 | ## Intro 4 | In this meetup, we will introudce the FLIR camera and microscope camera on Pi. Demo code can be found below. 5 | The slide is available on [Raspberry Pi特色相機介紹(熱成像攝影機+微距相機)](https://www.slideshare.net/raspberrypi-tw/raspberry-pi-78846465) 6 | 7 | Our environment is Pi 4 + 2020-02-05-raspbian-buster-full.img. 8 | 9 | ## Required 10 | ### Build v4l2loopback virtual device node. 11 | ```shell 12 | # Install Kernel Source and Header 13 | $ sudo apt-get update 14 | $ sudo apt-get install bc libncurses5-dev flex bison libssl-dev 15 | $ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update 16 | $ rpi-source 17 | 18 | # Install required module 19 | $ sudo pip3 install imutils 20 | ``` 21 | 22 | ### Install V4L2 Kernel Module 23 | ```shell 24 | $ cd ~ 25 | $ git clone https://github.com/umlaeute/v4l2loopback 26 | $ cd ~/v4l2loopback 27 | $ sudo make 28 | $ sudo make install 29 | $ sudo depmod -a 30 | $ sudo modprobe v4l2loopback 31 | ``` 32 | 33 | ### Enable FLIR Camera V4L2 34 | ```shell 35 | $ cd ~ 36 | $ git clone https://github.com/groupgets/LeptonModule 37 | $ cd ~/LeptonModule/software/v4l2lepton 38 | $ sed -i -e 's/video1/video0/g' v4l2lepton.cpp 39 | $ make 40 | $ sudo ./v4l2lepton /dev/video0 & 41 | Waiting for sink 42 | done reading, resets: 43 | ``` 44 | 45 | ## FLIR Camera Canny Edge Detection 46 | ```shell 47 | $ cd flir 48 | 49 | # FLIR image preview 50 | $ python3 flir_preview.py 51 | 52 | # FLIR image to Gray scale image preview 53 | $ python3 canny2.py 54 | 55 | # Canny edge detection WITHOUT blur 56 | $ python3 canny3.py 57 | 58 | # Canny edge detection with blur 59 | $ python3 canny4.py 60 | ``` 61 | 62 | ## FLIR Camera + Raspberry Pi Camera Alpha Blending 63 | ```shell 64 | $ python3 blend.py 65 | ``` 66 | 67 | 68 | ## USB Microscope 69 | 70 | ## Required 71 | ### Install Python-tesseract 72 | ```shell 73 | $ pip3 install pytesseract 74 | ``` 75 | 76 | ### Use [pytesseract](https://pypi.python.org/pypi/pytesseract) to do OCR. 77 | ```shell 78 | $ cd micro 79 | $ python3 ocr_preview.py 0 80 | ``` 81 | 82 | Note: 83 | 1. the `0` of `python ocr_preview.py 0` means the 0th video device node, such as `/dev/video0`. 84 | 2. When launch the program, press `t` to start Tesseract-OCR for the fixed area. 85 | 3. After finish Tesseract-OCR, the result will be shown on the preview window. 86 | 4. Press `q` to exit the program. 87 | 88 | -------------------------------------------------------------------------------- /flir/blend.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | # blend.py 7 | # FLIR Camera + Raspberry Pi Camera alpha blending 8 | # 9 | # Author : sosorry 10 | # Date : 2017/07/31 11 | # Usage : python blend.py 12 | 13 | import cv2 14 | import numpy as np 15 | import time 16 | import imutils 17 | 18 | def nothing(x): 19 | pass 20 | 21 | cv2.namedWindow('blend', cv2.WINDOW_NORMAL) 22 | cv2.createTrackbar('alpha', 'blend', 0, 10, nothing) 23 | 24 | # FLIR Camera 25 | flr = cv2.VideoCapture(1) 26 | 27 | # Raspberry Pi Camera 28 | cam = cv2.VideoCapture(0) 29 | 30 | while True: 31 | alpha = cv2.getTrackbarPos('alpha', 'blend') 32 | ret, img1 = flr.read() 33 | ret, img2 = cam.read() 34 | 35 | img1 = imutils.resize(img1, 320) 36 | img2 = imutils.resize(img2, 320) 37 | 38 | cv2.resizeWindow('blend', 320, 240) 39 | cam_alpha = float(alpha)/10 40 | flir_alpha = float(10-alpha)/10 41 | dst = cv2.addWeighted(img1, cam_alpha, img2, flir_alpha, 0) 42 | cv2.imshow("blend", dst) 43 | 44 | if cv2.waitKey(1) & 0xFF == ord("q"): 45 | break 46 | 47 | time.sleep(0.01) 48 | 49 | flr.release() 50 | cam.release() 51 | cv2.destroyAllWindows() 52 | 53 | -------------------------------------------------------------------------------- /flir/camera_preview.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | 7 | import cv2 8 | import time 9 | import imutils 10 | 11 | #cap = cv2.VideoCapture(1) 12 | cap = cv2.VideoCapture(0) 13 | #cap.set(PROP_FRAME_WIDTH, 80) 14 | #cap.set(PROP_FRAME_HEIGHT, 60) 15 | 16 | while True: 17 | ret, frame = cap.read() 18 | frame = imutils.resize(frame, 320) 19 | cv2.imshow("preview", frame) 20 | if cv2.waitKey(1) & 0xFF == ord("q"): 21 | break 22 | 23 | time.sleep(0.01) 24 | 25 | cap.release() 26 | cv2.destroyAllWindows() 27 | 28 | -------------------------------------------------------------------------------- /flir/canny1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | # canny1.py 7 | # FLIR Camera preview 8 | # 9 | # Author : sosorry 10 | # Date : 2017/07/31 11 | # Usage : python canny1.py 12 | 13 | import cv2 14 | import time 15 | import imutils 16 | 17 | vc = cv2.VideoCapture(1) 18 | 19 | if vc.isOpened(): # try to get the first frame 20 | rval, frame = vc.read() 21 | else: 22 | rval = False 23 | 24 | while rval: 25 | rval, frame = vc.read() 26 | frame = imutils.resize(frame, 320) 27 | cv2.imshow("flir", frame) 28 | 29 | if cv2.waitKey(1) & 0xFF == ord("q"): 30 | break 31 | 32 | time.sleep(0.01) 33 | 34 | vc.release() 35 | cv2.destroyAllWindows() 36 | -------------------------------------------------------------------------------- /flir/canny2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | # canny2.py 7 | # FLIR image to Gray scale image preview 8 | # 9 | # Author : sosorry 10 | # Date : 2017/07/31 11 | # Usage : python canny2.py 12 | 13 | import cv2 14 | import time 15 | import imutils 16 | 17 | vc = cv2.VideoCapture(1) 18 | 19 | if vc.isOpened(): # try to get the first frame 20 | rval, frame = vc.read() 21 | else: 22 | rval = False 23 | 24 | while rval: 25 | rval, frame = vc.read() 26 | frame = imutils.resize(frame, 320) 27 | frame_hsv = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV) 28 | cv2.imshow("gray", frame_hsv) 29 | 30 | if cv2.waitKey(1) & 0xFF == ord("q"): 31 | break 32 | 33 | time.sleep(0.01) 34 | 35 | vc.release() 36 | cv2.destroyAllWindows() 37 | -------------------------------------------------------------------------------- /flir/canny3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | # canny3.py 7 | # Canny edge detection WITHOUT blur 8 | # 9 | # Author : sosorry 10 | # Date : 2017/07/31 11 | # Usage : python canny3.py 12 | 13 | import cv2 14 | import time 15 | import imutils 16 | 17 | cv2.namedWindow('canny', cv2.WINDOW_NORMAL) 18 | vc = cv2.VideoCapture(1) 19 | 20 | if vc.isOpened(): # try to get the first frame 21 | rval, frame = vc.read() 22 | else: 23 | rval = False 24 | 25 | while rval: 26 | rval, frame = vc.read() 27 | frame = imutils.resize(frame, 320) 28 | frame_hsv = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV) 29 | frame_v = frame_hsv[:,:,2] 30 | thresh = 50 31 | edges = cv2.Canny(frame_v,thresh,thresh*2, L2gradient=True) 32 | cv2.resizeWindow('canny', 320, 240) 33 | cv2.imshow("canny", edges) 34 | 35 | if cv2.waitKey(1) & 0xFF == ord("q"): 36 | break 37 | 38 | time.sleep(0.01) 39 | 40 | vc.release() 41 | cv2.destroyAllWindows() 42 | -------------------------------------------------------------------------------- /flir/canny4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | # canny4.py 7 | # Canny edge detection with blur 8 | # 9 | # Author : sosorry 10 | # Date : 2017/07/31 11 | # Usage : python canny4.py 12 | 13 | import cv2 14 | import time 15 | import imutils 16 | 17 | cv2.namedWindow('canny', cv2.WINDOW_NORMAL) 18 | vc = cv2.VideoCapture(1) 19 | 20 | if vc.isOpened(): # try to get the first frame 21 | rval, frame = vc.read() 22 | else: 23 | rval = False 24 | 25 | while rval: 26 | rval, frame = vc.read() 27 | frame = imutils.resize(frame, 320) 28 | frame_hsv = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV) 29 | frame_v = frame_hsv[:,:,2] 30 | blurredBrightness = cv2.bilateralFilter(frame_v,9,150,150) 31 | thresh = 70 32 | edges = cv2.Canny(blurredBrightness,thresh,thresh*2, L2gradient=True) 33 | cv2.resizeWindow('canny', 320, 240) 34 | cv2.imshow("canny", edges) 35 | 36 | if cv2.waitKey(1) & 0xFF == ord("q"): 37 | break 38 | 39 | time.sleep(0.01) 40 | 41 | vc.release() 42 | cv2.destroyAllWindows() 43 | -------------------------------------------------------------------------------- /flir/flir_preview.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | # 6 | # flir_preview.py 7 | # Preview from camera 8 | # 9 | # Author : sosorry 10 | # Date : 04/18/2015 11 | # Usage : python flir_preview.py 12 | 13 | import cv2 14 | import time 15 | import imutils 16 | 17 | cap = cv2.VideoCapture(1) 18 | 19 | while True: 20 | ret, frame = cap.read() 21 | frame = imutils.resize(frame, 160) 22 | cv2.imshow("preview", frame) 23 | if cv2.waitKey(1) & 0xFF == ord("q"): 24 | break 25 | 26 | time.sleep(0.01) 27 | 28 | cap.release() 29 | cv2.destroyAllWindows() 30 | 31 | -------------------------------------------------------------------------------- /flir/horizontal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 4 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 5 | 6 | import cv2 7 | import numpy as np 8 | import time 9 | import imutils 10 | 11 | # FLIR Camera 12 | flr = cv2.VideoCapture(1) 13 | 14 | # Raspberry Pi Camera 15 | cam = cv2.VideoCapture(0) 16 | 17 | while True: 18 | ret, img1 = flr.read() 19 | ret, img2 = cam.read() 20 | 21 | img1 = imutils.resize(img1, 320) 22 | img2 = imutils.resize(img2, 320) 23 | 24 | horizontal = np.hstack((img1, img2)) 25 | 26 | cv2.imshow('horizontal', horizontal) 27 | 28 | if cv2.waitKey(1) & 0xFF == ord("q"): 29 | break 30 | 31 | time.sleep(0.01) 32 | 33 | flr.release() 34 | cam.release() 35 | cv2.destroyAllWindows() 36 | 37 | -------------------------------------------------------------------------------- /micro/ocr_preview.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 4 | #|R|a|s|p|b|e|r|r|y|P|i|.|c|o|m|.|t|w| 5 | #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6 | # 7 | # ocr_preview.py 8 | # Do OCR in fixed area. 9 | # 10 | # Author : sosorry 11 | # Date : 2017/07/31 12 | # Usage : python ocr_preview.py CAMERA_ID 13 | # Example: python ocr_preview.py 0 14 | 15 | import cv2 16 | import numpy as np 17 | import pytesseract 18 | from PIL import Image 19 | import sys 20 | 21 | 22 | camera_id = sys.argv[1] 23 | cap = cv2.VideoCapture( int(camera_id) ) 24 | cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 320) 25 | cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 240) 26 | 27 | src_file = "ocr.png" 28 | asciidata = None 29 | 30 | while True: 31 | ret, frame = cap.read() 32 | 33 | if asciidata is not None: 34 | cv2.rectangle(frame, (10, 190), (200, 230), (255, 255, 255), thickness=cv2.cv.CV_FILLED) 35 | cv2.putText(frame, asciidata, (10, 220), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), thickness=2) 36 | 37 | offset = 15 38 | x, y = 100, 50 39 | w, h = 230, 70 40 | cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) 41 | 42 | img = frame[y:y+h, x:x+w] 43 | img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 44 | kernel = np.ones((1, 1), np.uint8) 45 | img = cv2.dilate(img, kernel, iterations=3) 46 | img = cv2.erode(img, kernel, iterations=3) 47 | img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 33, 1) 48 | shift_img = img[offset:h+offset, offset:w+offset] 49 | cv2.imshow("preview", frame) 50 | cv2.imshow("ocr", shift_img) 51 | 52 | if cv2.waitKey(1) & 0xFF == ord("t"): 53 | cv2.imwrite("thres.png", shift_img) 54 | print '--- Start recognize text from image ---' 55 | data = pytesseract.image_to_string(Image.open("thres.png")) 56 | print data 57 | asciidata = data.encode("ascii","ignore") 58 | print "------ Done -------" 59 | 60 | if cv2.waitKey(1) & 0xFF == ord("q"): 61 | break 62 | 63 | cap.release() 64 | cv2.destroyAllWindows() 65 | 66 | --------------------------------------------------------------------------------