From 5b73cd0e1d47e604c3cad909118d9e0db15672a2 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 17 Sep 2016 10:25:43 +0000 Subject: [PATCH] - added git-svn-id: http://moon:8086/svn/software/trunk/projects/opencv@310 b431acfa-c32f-4a4a-93f1-934dc6c82436 --- PiVideoStream.py | 65 +++++++++++++ blobdetect_threaded.py | 93 +++++++++++++++++++ circledetect_threaded.py | 194 +++++++++++++++++++++++++++++++++++++++ fps_nonThreaded.py | 64 +++++++++++++ fps_threaded.py | 59 ++++++++++++ picam_test.py | 54 +++++++++++ thresh_threaded.py | 65 +++++++++++++ 7 files changed, 594 insertions(+) create mode 100755 PiVideoStream.py create mode 100755 blobdetect_threaded.py create mode 100755 circledetect_threaded.py create mode 100755 fps_nonThreaded.py create mode 100755 fps_threaded.py create mode 100755 picam_test.py create mode 100755 thresh_threaded.py diff --git a/PiVideoStream.py b/PiVideoStream.py new file mode 100755 index 0000000..ff3478b --- /dev/null +++ b/PiVideoStream.py @@ -0,0 +1,65 @@ +# import the necessary packages +from imutils.video import FPS +from picamera.array import PiRGBArray +from picamera import PiCamera +from threading import Thread +import cv2 + +class PiVideoStream: + def __init__(self, resolution=(320, 240), framerate=32): + # initialize the camera and stream + self.camera = PiCamera() + self.camera.resolution = resolution + self.camera.framerate = framerate + self.rawCapture = PiRGBArray(self.camera, size=resolution) + self.stream = self.camera.capture_continuous(self.rawCapture, + format="bgr", use_video_port=True) + + # initialize the frame and the variable used to indicate + # if the thread should be stopped + self.frame = None + self.stopped = False + self.fps = None + self.thread = None + self.startup = True + def start(self): + # start the thread to read frames from the video stream + self.thread = Thread(target=self.update, args=()) + self.thread.start() + return self + + def update(self): + # keep looping infinitely until the thread is stopped + for f in self.stream: + if self.startup: + self.fps = FPS().start() + self.startup = False + # grab the frame from the stream and clear the stream in + # preparation for the next frame + self.frame = f.array + self.rawCapture.truncate(0) + self.fps.update() + + # if the thread indicator variable is set, stop the thread + # and resource camera resources + if self.stopped: + self.fps.stop() + self.stream.close() + self.rawCapture.close() + self.camera.close() + return + + + def read(self): + # return the frame most recently read + return self.frame + + def stop(self): + # indicate that the thread should be stopped + self.stopped = True + if self.thread != None: + self.thread.join() + + def getfps(self): + return self.fps + diff --git a/blobdetect_threaded.py b/blobdetect_threaded.py new file mode 100755 index 0000000..037fc27 --- /dev/null +++ b/blobdetect_threaded.py @@ -0,0 +1,93 @@ +# import the necessary packages +from __future__ import print_function +from PiVideoStream import PiVideoStream +from imutils.video import FPS +from picamera.array import PiRGBArray +from picamera import PiCamera +import numpy as np +import argparse +import imutils +import time +import cv2 + +# construct the argument parse and parse the arguments +ap = argparse.ArgumentParser() +ap.add_argument("-n", "--num-frames", type=int, default=100, + help="# of frames to loop over for FPS test") +ap.add_argument("-d", "--display", type=int, default=-1, + help="Whether or not frames should be displayed") +args = vars(ap.parse_args()) + +# created a *threaded *video stream, allow the camera sensor to warmup, +# and start the FPS counter +print("[INFO] sampling THREADED frames from `picamera` module...") +vs = PiVideoStream(resolution=(640,480), framerate=30).start() +time.sleep(2.0) +fps = FPS().start() + +# Setup SimpleBlobDetector parameters. +params = cv2.SimpleBlobDetector_Params() + +# Change thresholds +params.minThreshold = 10; +params.maxThreshold = 200; + +# Filter by Area. +params.filterByArea = True +params.minArea = 200 + +# Filter by Circularity +params.filterByCircularity = True +params.minCircularity = 0.5 + +# Filter by Convexity +params.filterByConvexity = False +params.minConvexity = 0.87 + +# Filter by Inertia +params.filterByInertia = False +params.minInertiaRatio = 0.01 + +# Create a detector with the parameters +ver = (cv2.__version__).split('.') +if int(ver[0]) < 3 : + detector = cv2.SimpleBlobDetector(params) +else : + detector = cv2.SimpleBlobDetector_create(params) + +# loop over some frames...this time using the threaded stream +while fps._numFrames < args["num_frames"]: + # grab the frame from the threaded video stream + frame = vs.read() + + # Detect blobs. + keypoints = detector.detect(frame) + + # Draw detected blobs as red circles. + # cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob + im_with_keypoints = cv2.drawKeypoints(frame, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) + + # Show keypoints + cv2.imshow("Keypoints", im_with_keypoints) + cv2.waitKey(1) + + # check to see if the frame should be displayed to our screen + if args["display"] > 0: + if frame != None: + cv2.imshow("Frame", frame) + key = cv2.waitKey(10) & 0xFF + + # update the FPS counter + fps.update() + +# stop the timer and display FPS information +fps.stop() +vs.stop() +print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) +print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) +print("[INFO] Camera : elasped time: {:.2f}".format(vs.getfps().elapsed())) +print("[INFO] Camera: approx. FPS: {:.2f}".format(vs.getfps().fps())) + +# do a bit of cleanup +cv2.destroyAllWindows() + diff --git a/circledetect_threaded.py b/circledetect_threaded.py new file mode 100755 index 0000000..9b39b74 --- /dev/null +++ b/circledetect_threaded.py @@ -0,0 +1,194 @@ +# import the necessary packages +from __future__ import print_function +from PiVideoStream import PiVideoStream +from imutils.video import FPS +from picamera.array import PiRGBArray +from picamera import PiCamera +import numpy as np +import argparse +import imutils +import time +import cv2 +import pprint + +width = 320 +height = 240 + +class FindObjects(): + def __init__(self): + self.innerOuterRatio = 0.6 # const + self.meanThickness = 0 + self.meanOuterDiameter = 0 + self.meanInnerDiameter = 0 + self.maxDiameter = -10000 + self.minDiameter = +10000 + self.pp = pprint.PrettyPrinter(indent=4) + + @staticmethod + def getFamily(family, parentId, hierachy): + + family.append(parentId) + if hierachy[0][parentId][2] != -1: + return FindObjects.getFamily(family, hierachy[0][parentId][2], hierachy) + else: + return family + + + def find(self, contours, hierachy): + count = 0 + objects = [] + temp_objects = [] + objectsIds = [] + objectsCandIds = [] + for cnt in contours: + if hierachy[0][count][3] == -1: + family = FindObjects.getFamily([], count, hierachy) + + dupDict = {} + members = [] + for member in family: + x,y,w,h = cv2.boundingRect(contours[member]); + key = str([x,y,w,h]) + '.key' + if not key in dupDict: + dupDict[key] = member + members.append({ 'id' : member, 'bbox' : [x,y,w,h]}) + + objectsCandIds.append(members) + + count += 1 + + for family in objectsCandIds: + obj = [] + for member in family: + area = cv2.contourArea(contours[member['id']]) + perimeter = cv2.arcLength(contours[member['id']], True) + pi = 3.14159265359 + Q = 0 + if (perimeter > 0): + Q = 4*pi*area/(perimeter*perimeter) + + if Q >= 0.7: + diameter = max(member['bbox'][2], member['bbox'][3]) + self.maxDiameter = max(self.maxDiameter, diameter) + self.minDiameter = min(self.minDiameter, diameter) + member['diameter'] = diameter + member['pos'] = (int(member['bbox'][0] + member['bbox'][2]/2), int(member['bbox'][1] + member['bbox'][3]/2)) + obj.append(member) + + if obj: + temp_objects.append(obj) + + for obj in temp_objects: + for member in obj: + if member['diameter'] < self.innerOuterRatio*self.maxDiameter: + member['isHole'] = True + else: + member['isHole'] = False + + if len(obj) == 2: + self.meanThickness = int(abs(obj[0]['diameter'] - obj[1]['diameter'])/2) + + objects.append({'thickness' : self.meanThickness, 'members' : obj}) + +# self.pp.pprint(objects) + return objects + + def printStats(self): + print ("maxDiameter = " + str(self.maxDiameter) + " px") + print ("minDiameter = " + str(self.minDiameter) + " px") + print ("meanThickness = " + str(self.meanThickness) + " px") + +# construct the argument parse and parse the arguments +ap = argparse.ArgumentParser() +ap.add_argument("-n", "--num-frames", type=int, default=100, + help="# of frames to loop over for FPS test") +ap.add_argument("-d", "--display", type=int, default=-1, + help="Whether or not frames should be displayed") +args = vars(ap.parse_args()) + +# created a *threaded *video stream, allow the camera sensor to warmup, +# and start the FPS counter +print("[INFO] sampling THREADED frames from `picamera` module...") +vs = PiVideoStream(resolution=(width,height), framerate=30).start() +time.sleep(2.0) +fps = FPS().start() +findObjects = FindObjects() + +# loop over some frames...this time using the threaded stream +while fps._numFrames < args["num_frames"]: + # grab the frame from the threaded video stream + frame = vs.read() + gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) + gray_bluured = cv2.medianBlur(gray,5) + + # Canny edge detection + img1_canny = cv2.Canny(gray_bluured, 100, 50) + + # Thresholding +# ret,img1_thr = cv2.threshold(gray1,120,255,cv2.THRESH_BINARY) +# img1_thr = cv2.adaptiveThreshold(gray1,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2) +# img1_thr = cv2.adaptiveThreshold(gray1,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2) + + # Contours + (_, contours, hierachy) = cv2.findContours(img1_canny.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) + + objects = findObjects.find(contours, hierachy) + +# print (ids) + + img1_objects = frame.copy() + img1_colors = np.zeros((height,width,3), np.uint8) + maskCenter = 2 + roides = [] + for obj in objects: + memberCount = 0 + radius = 0 + roi = 0 + for member in obj['members']: + # Draw bounding box + x,y,w,h = [member['bbox'][0], member['bbox'][1], member['bbox'][2], member['bbox'][3]]; + if member['isHole']: + img1_objects = cv2.rectangle(img1_objects,(x,y),(x+w,y+h),(255,0,0),2) + thickness = obj['thickness']-maskCenter + radius = int((member['diameter']+thickness+maskCenter)/2) + roi = frame[y-thickness:y+2*radius, x-thickness:x+2*radius] + roides.append({'roi' : roi, 'pos' : member['pos'], 'radius' : radius, 'thickness' : thickness}) + else: + img1_objects = cv2.rectangle(img1_objects,(x,y),(x+w,y+h),(0,0,255),2) + + memberCount += 1 + + for r in roides: + if radius > 0: + radius = r['radius'] + thickness = r['thickness'] + roi = r['roi'] + pos = r['pos'] + mask = np.zeros((2*radius,2*radius,1), np.uint8) + mask = cv2.circle(mask,(radius, radius),radius,255,thickness) + mean_color = cv2.mean(roi) + center = (int(pos[0]),int(pos[1])) + img1_colors = cv2.circle(img1_colors,center,radius,mean_color,thickness) + + cv2.imshow('detected colors', img1_colors) +# cv2.imshow('Thresholded',img1_thr) + cv2.imshow('Canny',img1_canny) + cv2.imshow('Objects',img1_objects) + cv2.waitKey(1) + + # update the FPS counter + fps.update() + +findObjects.printStats() + +# stop the timer and display FPS information +fps.stop() +vs.stop() +print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) +print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) +print("[INFO] Camera : elasped time: {:.2f}".format(vs.getfps().elapsed())) +print("[INFO] Camera: approx. FPS: {:.2f}".format(vs.getfps().fps())) + +# do a bit of cleanup +cv2.destroyAllWindows() + diff --git a/fps_nonThreaded.py b/fps_nonThreaded.py new file mode 100755 index 0000000..c70c208 --- /dev/null +++ b/fps_nonThreaded.py @@ -0,0 +1,64 @@ +# import the necessary packages +from __future__ import print_function +from imutils.video.pivideostream import PiVideoStream +from imutils.video import FPS +from picamera.array import PiRGBArray +from picamera import PiCamera +import argparse +import imutils +import time +import cv2 + +# construct the argument parse and parse the arguments +ap = argparse.ArgumentParser() +ap.add_argument("-n", "--num-frames", type=int, default=100, + help="# of frames to loop over for FPS test") +ap.add_argument("-d", "--display", type=int, default=-1, + help="Whether or not frames should be displayed") +args = vars(ap.parse_args()) + +# initialize the camera and stream +camera = PiCamera() +camera.resolution = (320, 240) +camera.framerate = 32 +rawCapture = PiRGBArray(camera, size=(320, 240)) +stream = camera.capture_continuous(rawCapture, format="bgr", + use_video_port=True) + +# allow the camera to warmup and start the FPS counter +print("[INFO] sampling frames from `picamera` module...") +time.sleep(2.0) +fps = FPS().start() + +# loop over some frames +for (i, f) in enumerate(stream): + # grab the frame from the stream and resize it to have a maximum + # width of 400 pixels + frame = f.array + frame = imutils.resize(frame, width=400) + + # check to see if the frame should be displayed to our screen + if args["display"] > 0: + cv2.imshow("Frame", frame) + key = cv2.waitKey(1) & 0xFF + + # clear the stream in preparation for the next frame and update + # the FPS counter + rawCapture.truncate(0) + fps.update() + + # check to see if the desired number of frames have been reached + if i == args["num_frames"]: + break + +# stop the timer and display FPS information +fps.stop() +print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) +print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) + +# do a bit of cleanup +cv2.destroyAllWindows() +stream.close() +rawCapture.close() +camera.close() + diff --git a/fps_threaded.py b/fps_threaded.py new file mode 100755 index 0000000..4834f36 --- /dev/null +++ b/fps_threaded.py @@ -0,0 +1,59 @@ +# import the necessary packages +from __future__ import print_function +from PiVideoStream import PiVideoStream +from imutils.video import FPS +from picamera.array import PiRGBArray +from picamera import PiCamera +import numpy as np +import argparse +import imutils +import time +import cv2 + +# construct the argument parse and parse the arguments +ap = argparse.ArgumentParser() +ap.add_argument("-n", "--num-frames", type=int, default=100, + help="# of frames to loop over for FPS test") +ap.add_argument("-d", "--display", type=int, default=-1, + help="Whether or not frames should be displayed") +args = vars(ap.parse_args()) + +# created a *threaded *video stream, allow the camera sensor to warmup, +# and start the FPS counter +print("[INFO] sampling THREADED frames from `picamera` module...") +vs = PiVideoStream(resolution=(320,240), framerate=30).start() +time.sleep(2.0) +fps = FPS().start() + +# loop over some frames...this time using the threaded stream +while fps._numFrames < args["num_frames"]: + # grab the frame from the threaded video stream + frame = vs.read() + + hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) + h,s,v = cv2.split(hsv) + img = cv2.merge((h,s,v)) + rgb = cv2.cvtColor(img, cv2.COLOR_HSV2BGR) + + # check to see if the frame should be displayed to our screen + if args["display"] > 0: + if frame != None: + cv2.imshow("Frame", rgb) + key = cv2.waitKey(10) & 0xFF + else: + time.sleep(0.5) + + # update the FPS counter + fps.update() + +# stop the timer and display FPS information +fps.stop() +vs.stop() +print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) +print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) +print("[INFO] Camera : elasped time: {:.2f}".format(vs.getfps().elapsed())) +print("[INFO] Camera: approx. FPS: {:.2f}".format(vs.getfps().fps())) + +# do a bit of cleanup +cv2.destroyAllWindows() + diff --git a/picam_test.py b/picam_test.py new file mode 100755 index 0000000..7e0db88 --- /dev/null +++ b/picam_test.py @@ -0,0 +1,54 @@ +# import the necessary packages +from __future__ import print_function +from imutils.video import FPS +from picamera import PiCamera +from picamera import CircularIO +import imutils +import time +import cv2 + +class MyCameraIo(object): + def __init__(self, frameSize): + print("MyCameraIo") + self.frameSize = frameSize[0]*frameSize[1] + self.size = 0 + self.frames = 0 + self.fps = None + + def writable(self): + return True + + def write(self, data): + if self.size == 0: + self.fps = FPS().start() + + self.size += len(data) + self.frames += len(data)/(3*self.frameSize) + + def size(self): + print("size") + return self.size + + def flush(self): + if self.size > 0: + self.fps.stop() + print("Recorded " + str(self.frames) + " frames (" + str(self.size) + " bytes)") + print("FPS = " + str(self.frames/self.fps.elapsed())) + + +# initialize the camera and stream +camera = PiCamera() +camera.resolution = (320, 240) +camera.framerate = 90 + +myCameraIo = MyCameraIo(camera.resolution) +camera.start_recording(myCameraIo, format="bgr") + +# allow the camera to warmup and start the FPS counter +print("[INFO] sampling frames from `picamera` module...") +time.sleep(10.0) + +# do a bit of cleanup +cv2.destroyAllWindows() +camera.close() + diff --git a/thresh_threaded.py b/thresh_threaded.py new file mode 100755 index 0000000..39802dd --- /dev/null +++ b/thresh_threaded.py @@ -0,0 +1,65 @@ +# import the necessary packages +from __future__ import print_function +from PiVideoStream import PiVideoStream +from imutils.video import FPS +from picamera.array import PiRGBArray +from picamera import PiCamera +import numpy as np +import argparse +import imutils +import time +import cv2 + +# construct the argument parse and parse the arguments +ap = argparse.ArgumentParser() +ap.add_argument("-n", "--num-frames", type=int, default=100, + help="# of frames to loop over for FPS test") +ap.add_argument("-d", "--display", type=int, default=-1, + help="Whether or not frames should be displayed") +args = vars(ap.parse_args()) + +# created a *threaded *video stream, allow the camera sensor to warmup, +# and start the FPS counter +print("[INFO] sampling THREADED frames from `picamera` module...") +vs = PiVideoStream(resolution=(640,480), framerate=30).start() +time.sleep(2.0) +fps = FPS().start() + +# Initiate FAST object with default values +fast = cv2.FastFeatureDetector_create() +fast.setNonmaxSuppression(True) + +# loop over some frames...this time using the threaded stream +while fps._numFrames < args["num_frames"]: + # grab the frame from the threaded video stream + frame = vs.read() + temp = frame + + # find and draw the keypoints + kp = fast.detect(frame,None) + img2 = cv2.drawKeypoints(frame, kp, outImage=temp, color=(255,0,0)) + + # Print all default params + print ("Threshold: " + str(fast.getThreshold())) + print ("nonmaxSuppression: " + str(fast.getNonmaxSuppression())) + print ("neighborhood: " + str(fast.getType())) + print ("Total Keypoints with nonmaxSuppression: " + str(len(kp))) + + # check to see if the frame should be displayed to our screen + cv2.imshow("Frame", img2) + key = cv2.waitKey(1) & 0xFF + + # update the FPS counter + fps.update() + +# stop the timer and display FPS information +fps.stop() +vs.stop() +print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) +print("[INFO] approx. FPS: {:.2f}".format(fps.fps())) +print("[INFO] Camera : elasped time: {:.2f}".format(vs.getfps().elapsed())) +print("[INFO] Camera: approx. FPS: {:.2f}".format(vs.getfps().fps())) + +# do a bit of cleanup +cv2.destroyAllWindows() +