--- a +++ b/CvImage.py @@ -0,0 +1,126 @@ +import cv2 +import imutils +import numpy as np +from math import sqrt + +def abs (n): + if n >= 0: + return n + return abs((-1 * n)) + +class CvImage: + def __init__ (self, image, name): + self.__name = name + self.__originalImage = image + self.__image = image + self.__contours = False + self.__contoursFeatures = False + + def getName (self): + return self.__name + + def getOriginalImage (self): + return self.__originalImage + + def getImage (self): + return self.__image + + def drawCircle (self, center, radious = 1, color = (0, 255, 0), thickness = 2): + cv2.circle(self.__image, center, radious, color, thickness) + + def drawContours (self, contours, color = (0, 255, 0), thickness = 2): + cv2.drawContours(self.__image, contours, -1, color, thickness) + + def __show (self, name, image): + cv2.imshow(name, image) + cv2.waitKey(0) + + def showOriginal (self): + self.__show(self.__name + "-original", self.getOriginalImage()) + + def show (self): + self.__show(self.__name, self.__image) + + def morphOperations (self, kernelSize = 3): + # Open and close morph operations + kernel = np.ones((kernelSize, kernelSize),np.uint8) + self.__image = cv2.morphologyEx(self.__image, cv2.MORPH_OPEN, kernel) + self.__image = cv2.morphologyEx(self.__image, cv2.MORPH_CLOSE, kernel) + + def hsvFilter (self, lowerHSV, higherHSV): + # Convert to HSV + self.__image = cv2.cvtColor(self.__image, cv2.COLOR_BGR2HSV) + + # InRange filter + self.__image = cv2.inRange(self.__image, lowerHSV, higherHSV) + + + def getContours(self): + if self.__contours == False: + self.__contours = self.__findCountours() + return self.__contours + + def getContoursFeatures(self, n = 5): + if self.__contoursFeatures == False: + self.__contoursFeatures = self.__findContoursFeatures(n) + return self.__contoursFeatures + + def gray2bgr (self): + self.__image = cv2.cvtColor(self.__image, cv2.COLOR_GRAY2BGR) + + def bgr2gray (self): + self.__image = cv2.cvtColor(self.__image, cv2.COLOR_BGR2GRAY) + + def __findCountours(self): + # ConvertToGrayScale and filter + gray = cv2.bilateralFilter(self.__image, 11, 17, 17) + + # Edge algoritm + edged = cv2.Canny(gray, 30, 200) + + cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + cnts = imutils.grab_contours(cnts) + + # Sort by larger areas + cnts = sorted(cnts, key = cv2.contourArea, reverse = True) + return cnts + + def __findContoursFeatures (self, minArea): + contoursFeatures = [] + cnts = self.getContours() + for i in range(0, len(cnts)): + if cv2.contourArea(cnts[i]) >= minArea: + # Compute the center of the contour + M = cv2.moments(cnts[i]) + cx = int(M["m10"] / M["m00"]) + cy = int(M["m01"] / M["m00"]) + + # Get some basic features + perimeter = cv2.arcLength(cnts[i], True) + epsilon = 0.1*perimeter + approx = cv2.approxPolyDP(cnts[i],epsilon,True) + + # Calculate eccentricity + (x, y), (MA, ma), angle = cv2.fitEllipse(cnts[i]) + a = ma/2 + b = MA/2 + + if (a > b): + eccentricity = sqrt(pow(a, 2)-pow(b, 2)) + eccentricity = round(eccentricity/a, 2) + else: + eccentricity = sqrt(pow(b, 2)-pow(a, 2)) + eccentricity = round(eccentricity/b, 2) + + # Append features + contoursFeatures.append({ + "area": cv2.contourArea(cnts[i]), + "perimeter": perimeter, + "eccentricity": eccentricity, + "centroid": (cx, cy), + "approxDp": np.squeeze(approx), + "convexHull": np.squeeze(cv2.convexHull(cnts[i])) + }) + else: + break + return contoursFeatures \ No newline at end of file