def adaptiveThreshold(self, method, threshstyle, kernel, const, ceilvalue=255, forceBW=False, inplace=False): """Applyes adaptiveThreshold to image Arguments: method {str} -- adaptive method ('m', 'mean' <=> cv2.ADAPTIVE_THRESH_MEAN_C), ('g', 'gaussian' <=> cv2.ADAPTIVE_THRESH_GAUSSIAN_C) threshstyle {cv2 enum} -- Style of thrsholding (cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV, cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC) kernel {int} -- size of kernel for mean or gaussian computation (Must be ODD) const {int} -- constant subtracted by the computed mean Keyword Arguments: ceilvalue {int} -- value used as maximum value for ceiling thresholding in THRESH_BINARY and THRESH_BINARY_INVERTED styles {Default: 255} forceBW {Boolean}: if true the image is transformed to BW regardless of its previous state, otherwise it expectes a BW image {Default: False} inplace {Boolean}: if true the transformation is made in place, else the transformed image is returned as a new spimage class {Default: False} """ if not self.bw and not forceBW: raise spe.NonBWImageException("threshold can only be applied to BW images") method = method.lower()[0] if 'm' in method: met = cv2.ADAPTIVE_THRESH_MEAN_C elif 'g' in method: met = cv2.ADAPTIVE_THRESH_GAUSSIAN_C else: raise spe.InvalidParameterException('value "' + method + '" is invalid for "method" parameter') bwimg = self.toBW(inplace=False) if inplace: self.img = cv2.adaptiveThreshold(bwimg.img, ceilvalue, met, threshstyle, kernel, const) self.bw = True else: return spimage(cv2.adaptiveThreshold(bwimg.img, ceilvalue, met, threshstyle, kernel, const))
def clearNoise(self, kernel, noisecolor='w', forceBW=False, inplace=False): """Clear noise dots Arguments: kernel {[int] or (int, int)} -- kernel size for erosion. If only one number, the kernel is assumed squared (Must be ODD) Keyword Arguments: noisecolor {str}: color of noise. Either black ('b') or white ('w') {Default: 'w'} forceBW {Boolean}: if true the image is transformed to BW regardless of its previous state, otherwise it expectes a BW image {Default: False} inplace {Boolean}: if true the transformation is made in place, else the transformed image is returned as a new spimage class {Default: False} """ if not self.bw and not forceBW: raise spe.NonBWImageException("clearNoise can only be applied to BW images") # define tranformation type nc = noisecolor.lower()[0] if 'b' in nc: morph = cv2.MORPH_CLOSE else: morph = cv2.MORPH_OPEN if isinstance(kernel, int): kernel = (kernel, kernel) if inplace: if not self.bw: self.toBW(inplace=True) self.img = cv2.morphologyEx(self.img, morph, kernel) else: cp = self.toBW(inplace=False) cp.clearNoise(kernel, noisecolor=nc, inplace=True) return cp
def getHoughLines(self, rhoacc, thetacc, minLen): """retrieve lines from image Arguments: rhoacc {float} -- Accuracy on rho computation thetacc {float} -- accuracy on theta computation minLen {float} -- minimum length for a line to be recognized as such Returns: lines {[(float, float)]} -- list of lines described by rho and theta """ if not self.bw: raise spe.NonBWImageException("getHoughLines can only be performed on BW images") return list(map(lambda x: x[0], cv2.HoughLines(self.img, rhoacc, thetacc, minLen)))
def getContours(self, retrmode, approxmode, filterfunc=None): """finds contours in the image Arguments: retrmode {cv2 enum} -- retrieval mode, representing the resulting hierarchy structure approxmode {cv2 enum} -- approximation mode Keyword Arguments: filterfunc {lambda function} -- filtering function {Default: None} Returns: contours {[contours], [hierarchy]} """ if not self.bw: raise spe.NonBWImageException("getContours can only be performed on BW images") im2, contours, hierarchy = cv2.findContours(self.img, retrmode, approxmode) if filterfunc is not None: contours = list(filter(filterfunc, contours)) return contours, hierarchy
def simpleThreshold(self, threshvalue, threshstyle, ceilvalue=255, forceBW=False, inplace=False): """Thresholds image Arguments: threshvalue {int} -- value used for thresholding comparison threshstyle {cv2 enum} -- Style of thrsholding (cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV, cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC) Keyword Arguments: ceilvalue {int} -- value used as maximum value for ceiling thresholding in THRESH_BINARY and THRESH_BINARY_INVERTED styles {Default: 255} forceBW {Boolean}: if true the image is transformed to BW regardless of its previous state, otherwise it expectes a BW image {Default: False} inplace {Boolean}: if true the transformation is made in place, else the transformed image is returned as a new spimage class {Default: False} """ if not self.bw and not forceBW: raise spe.NonBWImageException("threshold can only be applied to BW images") bwimg = self.toBW(inplace=False) if inplace: self.img = cv2.threshold(bwimg.img, threshvalue, ceilvalue, threshstyle)[1] self.bw = True else: return spimage(cv2.threshold(bwimg.img, threshvalue, ceilvalue, threshstyle)[1])
def getOtsuThreshold(self, ceilvalue=255, immediate=False, inplace=False, forceBW=False): """Gets the best thresholding parameter for BIMODAL images using OTSU's method Keyword Arguments: ceilvalue {int} -- value used as maximum value for ceiling thresholding in THRESH_BINARY and THRESH_BINARY_INVERTED styles {Default: 255} immediate {Boolean} -- if true the thresholding is also immediately applied on the image (or on a copy depending on inplace), else the value is returned forceBW {Boolean}: if true the image is transformed to BW regardless of its previous state, otherwise it expectes a BW image {Default: False} inplace {Boolean}: if true the transformation is made in place, else the transformed image is returned as a new spimage class {Default: False} Return: val {int} -- if NOT immediate, is the suggested threshold computed by the OTSU algorithm """ if not self.bw and not forceBW: raise spe.NonBWImageException("Otsu can only be computed on BW images") val, thresh = cv2.threshold(self.img, 0, ceilvalue, cv2.THRESH_BINARY + cv2.THRESH_OTSU) if immediate and inplace: self.img = thresh self.bw = True elif immediate and not inplace: return spimage(thresh) else: return val
def applyMorphTrans(self, transform, kernel, forceBW=False, inplace=False): """Applies CV2 morphological transform Arguments: transform {cv2 enum} -- transform to apply (cv2.MORPH_TOPHAT, cv2.MORPH_BLACKHAT, cv2.MORPH_GRADIENT) kernel {[int] or (int, int)} -- kernel size for erosion. If only one number, the kernel is assumed squared (Must be ODD) Keyword Arguments: forceBW {Boolean}: if true the image is transformed to BW regardless of its previous state, otherwise it expectes a BW image {Default: False} inplace {Boolean}: if true the transformation is made in place, else the transformed image is returned as a new spimage class {Default: False} """ if not self.bw and not forceBW: raise spe.NonBWImageException("applyMorphTrans can only be applied to BW images") if isinstance(kernel, int): kernel = (kernel, kernel) if inplace: if not self.bw: self.toBW(inplace=True) self.img = cv2.morphologyEx(self.img, transform, kernel) else: cp = self.toBW(inplace=False) cp.applyMorphTrans(kernel, transform=transform, inplace=True) return cp
def erode(self, kernel, reps=1, forceBW=False, inplace=False): """Applies CV2 erode function Arguments: kernel {[int] or (int, int)} -- kernel size for erosion. If only one number, the kernel is assumed squared (Must be ODD) Keyword Arguments: reps {int}: number of iteration of the algorithm {Default: 1} forceBW {Boolean}: if true the image is transformed to BW regardless of its previous state, otherwise it expectes a BW image {Default: False} inplace {Boolean}: if true the transformation is made in place, else the transformed image is returned as a new spimage class {Default: False} """ if not self.bw and not forceBW: raise spe.NonBWImageException("erode can only be applied to BW images") if isinstance(kernel, int): kernel = (kernel, kernel) if inplace: if not self.bw: self.toBW(inplace=True) self.img = cv2.erode(self.img, kernel, iterations=reps) else: cp = self.toBW(inplace=False) cp.erode(kernel, reps=reps, inplace=True) return cp