def grab_cut_mask(img_col, mask, debug=False): assert isinstance(img_col, numpy.ndarray), 'image must be a numpy array' assert isinstance(mask, numpy.ndarray), 'mask must be a numpy array' assert img_col.ndim == 3, 'skin detection can only work on color images' assert mask.ndim == 2, 'mask must be 2D' kernel = numpy.ones((50, 50), numpy.float32) / (50 * 50) dst = cv2.filter2D(mask, -1, kernel) dst[dst != 0] = 255 free = numpy.array(cv2.bitwise_not(dst), dtype=numpy.uint8) if debug: scripts.display('not skin', free) scripts.display('grabcut input', mask) grab_mask = numpy.zeros(mask.shape, dtype=numpy.uint8) grab_mask[:, :] = 2 grab_mask[mask == 255] = 1 grab_mask[free == 255] = 0 if numpy.unique(grab_mask).tolist() == [0, 1]: logger.debug('conducting grabcut') bgdModel = numpy.zeros((1, 65), numpy.float64) fgdModel = numpy.zeros((1, 65), numpy.float64) if img_col.size != 0: mask, bgdModel, fgdModel = cv2.grabCut(img_col, grab_mask, None, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK) mask = numpy.where((mask == 2) | (mask == 0), 0, 1).astype(numpy.uint8) else: logger.warning('img_col is empty') return mask
def get_rgb_mask(img, debug=False): assert isinstance(img, numpy.ndarray), 'image must be a numpy array' assert img.ndim == 3, 'skin detection can only work on color images' logger.debug('getting rgb mask') lower_thresh = numpy.array([45, 52, 108], dtype=numpy.uint8) upper_thresh = numpy.array([255, 255, 255], dtype=numpy.uint8) mask_a = cv2.inRange(img, lower_thresh, upper_thresh) mask_b = 255 * ((img[:, :, 2] - img[:, :, 1]) / 20) mask_c = 255 * ((numpy.max(img, axis=2) - numpy.min(img, axis=2)) / 20) mask_a = mask_a.astype(float) print(mask_a.dtype) print(mask_b.dtype) print(mask_c.dtype) msk_rgb = cv2.bitwise_and(mask_a, mask_b) msk_rgb = cv2.bitwise_and(mask_c, msk_rgb) msk_rgb[msk_rgb < 128] = 0 msk_rgb[msk_rgb >= 128] = 255 if debug: scripts.display('input', img) scripts.display('mask_rgb', msk_rgb) return msk_rgb.astype(float)
def main(args): assert isinstance(args, argparse.Namespace), 'args must be of type argparse.Namespace not {0}'.format(type(args)) sift = cv2.SIFT() flann = cv2.FlannBasedMatcher({'algorithm': 0, 'trees': 5}, {'checks': 50}) result, result_gry = None, None for path in args.paths: try: assert os.path.exists(path), '{0} is not a valid path'.format(path) logger.info('processing {0}'.format(path)) cam = cv2.VideoCapture(path) logger.debug('opened video') count = 0 while True: logger.debug('reading frame {0}'.format(count)) ret, frame = cam.read() logger.debug('cropping frame to minimise distortions') #todo: Crop frame! if ret: logger.debug('frame read correctly') count += 1 if result is not None and result_gry is not None: frame_gry = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) logger.debug('computing sift features') keypoints0, descriptors0 = sift.detectAndCompute(result_gry, None) keypoints1, descriptors1 = sift.detectAndCompute(frame_gry, None) logger.debug('finding correspondence') matches = flann.knnMatch(descriptors0, descriptors1, k=args.knn) positive = [] for match0, match1 in matches: if match0.distance < args.lowe*match1.distance: positive.append(match0) if len(positive) > args.min_correspondence: src_pts = numpy.array([keypoints0[good_match.queryIdx].pt for good_match in positive], dtype=numpy.float32) src_pts = src_pts.reshape((-1, 1, 2)) dst_pts = numpy.array([keypoints1[good_match.trainIdx].pt for good_match in positive], dtype=numpy.float32) dst_pts = dst_pts.reshape((-1, 1, 2)) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) result = combine.combine_images(frame, result, M) if args.display and not args.quiet: scripts.display('result', result) if cv2.waitKey(25) & 0xFF == ord('q'): break else: logger.warning('too few correspondence points') else: result = frame result_gry = cv2.cvtColor(result, cv2.COLOR_RGB2GRAY) else: break logger.debug('{0} is completed'.format(path)) cam.release() cv2.destroyAllWindows() if args.save: scripts.save_image(path, result) except Exception as error: logger.warning('Failed to process {0}'.format(path)) logger.debug('Error msg: {0}'.format(error)) return result
def get_mask_ycrcb(self, img): self.assert_image(img) lower_thresh = numpy.array([90, 100, 130], dtype=numpy.uint8) upper_thresh = numpy.array([230, 120, 180], dtype=numpy.uint8) img_ycrcb = cv2.cvtColor(img, cv2.COLOR_RGB2YCR_CB) msk_ycrcb = cv2.inRange(img_ycrcb, lower_thresh, upper_thresh) if self.args.debug: scripts.display('input', img) scripts.display('mask_ycrcb', msk_ycrcb) self.add_mask(msk_ycrcb)
def get_mask_ycrcb(self, img): self.assert_image(img) lower_thresh = numpy.array([90, 100, 130], dtype=numpy.uint8) upper_thresh = numpy.array([230, 120, 180], dtype=numpy.uint8) img_ycrcb = cv2.cvtColor(img, cv2.COLOR_RGB2YCR_CB) msk_ycrcb = cv2.inRange(img_ycrcb, lower_thresh, upper_thresh) if self.args.debug: scripts.display("input", img) scripts.display("mask_ycrcb", msk_ycrcb) self.add_mask(msk_ycrcb)
def get_mask_hsv(self, img): logger.debug('Applying hsv threshold') self.assert_image(img) lower_thresh = numpy.array([0, 50, 0], dtype=numpy.uint8) upper_thresh = numpy.array([120, 150, 255], dtype=numpy.uint8) img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) msk_hsv = cv2.inRange(img_hsv, lower_thresh, upper_thresh) if self.args.debug: scripts.display('input', img) scripts.display('mask_hsv', msk_hsv) self.add_mask(msk_hsv)
def get_mask_hsv(self, img): logger.debug("Applying hsv threshold") self.assert_image(img) lower_thresh = numpy.array([0, 50, 0], dtype=numpy.uint8) upper_thresh = numpy.array([120, 150, 255], dtype=numpy.uint8) img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) msk_hsv = cv2.inRange(img_hsv, lower_thresh, upper_thresh) if self.args.debug: scripts.display("input", img) scripts.display("mask_hsv", msk_hsv) self.add_mask(msk_hsv)
def get_mask_rgb(self, img): logger.debug('Applying rgb thresholds') lower_thresh = numpy.array([45, 52, 108], dtype=numpy.uint8) upper_thresh = numpy.array([255, 255, 255], dtype=numpy.uint8) mask_a = cv2.inRange(img, lower_thresh, upper_thresh) mask_b = 255*((img[:, :, 2]-img[:, :, 1])/20) logger.debug('mask_b unique: {0}'.format(numpy.unique(mask_b))) mask_c = 255*((numpy.max(img, axis=2)-numpy.min(img, axis=2))/20) logger.debug('mask_d unique: {0}'.format(numpy.unique(mask_c))) msk_rgb = cv2.bitwise_and(mask_a, mask_b) msk_rgb = cv2.bitwise_and(mask_c, msk_rgb) if self.args.debug: scripts.display('input', img) scripts.display('mask_rgb', msk_rgb) self.add_mask(msk_rgb)
def get_hsv_mask(img, debug=False): assert isinstance(img, numpy.ndarray), 'image must be a numpy array' assert img.ndim == 3, 'skin detection can only work on color images' logger.debug('getting hsv mask') lower_thresh = numpy.array([0, 50, 0], dtype=numpy.uint8) upper_thresh = numpy.array([120, 150, 255], dtype=numpy.uint8) img_hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) msk_hsv = cv2.inRange(img_hsv, lower_thresh, upper_thresh) msk_hsv[msk_hsv < 128] = 0 msk_hsv[msk_hsv >= 128] = 1 if debug: scripts.display('input', img) scripts.display('mask_hsv', msk_hsv) return msk_hsv.astype(float)
def get_ycrcb_mask(img, debug=False): assert isinstance(img, numpy.ndarray), 'image must be a numpy array' assert img.ndim == 3, 'skin detection can only work on color images' logger.debug('getting ycrcb mask') lower_thresh = numpy.array([90, 100, 130], dtype=numpy.uint8) upper_thresh = numpy.array([230, 120, 180], dtype=numpy.uint8) img_ycrcb = cv2.cvtColor(img, cv2.COLOR_RGB2YCR_CB) msk_ycrcb = cv2.inRange(img_ycrcb, lower_thresh, upper_thresh) msk_ycrcb[msk_ycrcb < 128] = 0 msk_ycrcb[msk_ycrcb >= 128] = 1 if debug: scripts.display('input', img) scripts.display('mask_ycrcb', msk_ycrcb) return msk_ycrcb.astype(float)
def evaluate(img_col, args): numpy.seterr(all='ignore') assert isinstance(img_col, numpy.ndarray), 'img_col must be a numpy array' assert img_col.ndim == 3, 'img_col must be a color image ({0} dimensions currently)'.format(img_col.ndim) assert isinstance(args, argparse.Namespace), 'args must be of type argparse.Namespace not {0}'.format(type(args)) img_gry = cv2.cvtColor(img_col, cv2.COLOR_RGB2GRAY) rows, cols = img_gry.shape crow, ccol = rows/2, cols/2 f = numpy.fft.fft2(img_gry) fshift = numpy.fft.fftshift(f) fshift[crow-75:crow+75, ccol-75:ccol+75] = 0 f_ishift = numpy.fft.ifftshift(fshift) img_fft = numpy.fft.ifft2(f_ishift) img_fft = 20*numpy.log(numpy.abs(img_fft)) if args.display and not args.testing: cv2.destroyAllWindows() scripts.display('img_fft', img_fft) scripts.display('img_col', img_col) cv2.waitKey(0) result = numpy.mean(img_fft) return img_fft, result, result < args.thresh
def evaluate(img_col, args): numpy.seterr(all='ignore') assert isinstance(img_col, numpy.ndarray), 'img_col must be a numpy array' assert img_col.ndim == 3, 'img_col must be a color image ({0} dimensions currently)'.format(img_col.ndim) assert isinstance(args, argparse.Namespace), 'args must be of type argparse.Namespace not {0}'.format(type(args)) img_gry = cv2.cvtColor(img_col, cv2.COLOR_RGB2GRAY) rows, cols = img_gry.shape crow, ccol = rows//2, cols//2 f = numpy.fft.fft2(img_gry) fshift = numpy.fft.fftshift(f) fshift[crow-75:crow+75, ccol-75:ccol+75] = 0 f_ishift = numpy.fft.ifftshift(fshift) img_fft = numpy.fft.ifft2(f_ishift) img_fft = 20*numpy.log(numpy.abs(img_fft)) if args.display and not args.testing: cv2.destroyAllWindows() scripts.display('img_fft', img_fft) scripts.display('img_col', img_col) cv2.waitKey(0) result = numpy.mean(img_fft) return img_fft, result, result < args.thresh
def evaluate(img_col, args): numpy.seterr(all='ignore') assert isinstance(img_col, numpy.ndarray), 'img_col must be a numpy array' assert img_col.ndim == 3, 'img_col must be a color image ({0} dimensions currently)'.format(img_col.ndim) assert isinstance(args, argparse.Namespace), 'args must be of type argparse.Namespace not {0}'.format(type(args)) img_gry = cv2.cvtColor(img_col, cv2.COLOR_RGB2GRAY) rows, cols = img_gry.shape crow, ccol = rows/2, cols/2 cv2.imwrite("test.png",img_gry) data = Image.open("test.png") remmax = lambda x: x/x.max() remmin = lambda x: x - numpy.amin(x, axis=(0,1), keepdims=True) touint8 = lambda x: (remmax(remmin(x))*(256-1e-4)).astype(int) channels = data.split() result_array = numpy.zeros_like(data) f = numpy.fft.fft2(channels[0]) fshift = numpy.fft.fftshift(f) fshift[int(crow-1):int(crow+1), int(ccol-1):int(ccol+1)] = 0 result_array[...]=touint8(fshift) result_image = Image.fromarray(result_array) result_image.save('out.png') print(numpy.count_nonzero(result_array > 128 )) fshift[int(crow-75):int(crow+75), int(ccol-75):int(ccol+75)] = 0 f_ishift = numpy.fft.ifftshift(fshift) img_fft = numpy.fft.ifft2(f_ishift) img_fft = 20*numpy.log(numpy.abs(img_fft)) if args.display and not args.testing: cv2.destroyAllWindows() scripts.display('img_fft', img_fft) scripts.display('img_col', img_col) cv2.waitKey(0) result = numpy.mean(img_fft) print (result) return img_fft, result, result < args.thresh
else: return evaluate(img_col=img_col, args=args) if __name__ == '__main__': args = scripts.get_args() logger = scripts.get_logger(quite=args.quite, debug=args.debug) x_okay, y_okay = [], [] x_blur, y_blur = [], [] for path in args.image_paths: for img_path in scripts.find_images(path): logger.debug('evaluating {0}'.format(img_path)) img = cv2.imread(img_path) if isinstance(img, numpy.ndarray): if args.testing: scripts.display('dialog (blurry: Y?)', img) blurry = False if cv2.waitKey(0) in map(lambda i: ord(i), ['Y', 'y']): blurry = True x_axis = [1, 3, 5, 7, 9] for x in x_axis: img_mod = cv2.GaussianBlur(img, (x, x), 0) y = evaluate(img_mod, args=args)[0] if blurry: x_blur.append(x) y_blur.append(y) else: x_okay.append(x) y_okay.append(y) elif args.mask: msk, res, blurry = FocusMask.blur_mask(img)
dst_pts = dst_pts.reshape((-1, 1, 2)) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) result = combine.combine_images(frame, result, M) if args.display and not args.quiet: scripts.display('result', result) if cv2.waitKey(25) & 0xFF == ord('q'): break else: logger.warning('too few correspondence points') else: result = frame result_gry = cv2.cvtColor(result, cv2.COLOR_RGB2GRAY) else: break logger.debug('{0} is completed'.format(path)) cam.release() cv2.destroyAllWindows() if args.save: scripts.save_image(path, result) except Exception as error: logger.warning('Failed to process {0}'.format(path)) logger.debug('Error msg: {0}'.format(error)) return result if __name__ == '__main__': args = scripts.get_args() logger = scripts.get_logger(quiet=args.quiet, debug=args.debug) result = main(args) scripts.display('final result', result) cv2.waitKey(0)
msk[:, w - dw:] = 255 return msk def blur_mask(img): assert isinstance(img, numpy.ndarray), 'img_col must be a numpy array' assert img.ndim == 3, 'img_col must be a color image ({0} dimensions currently)'.format( img.ndim) msk, val, blurry = main.blur_detector(img) logger.debug('inverting img_fft') msk = cv2.convertScaleAbs(255 - (255 * msk / numpy.max(msk))) msk[msk < 50] = 0 msk[msk > 127] = 255 logger.debug('removing border') msk = remove_border(msk) logger.debug('applying erosion and dilation operators') msk = morphology(msk) logger.debug('evaluation complete') result = numpy.sum(msk) / (255.0 * msk.size) logger.info('{0}% of input image is blurry'.format(int(100 * result))) return msk, result, blurry if __name__ == '__main__': img_path = raw_input("Please Enter Image Path: ") img = cv2.imread(img_path) msk, val = blur_mask(img) scripts.display('img', img) scripts.display('msk', msk) cv2.waitKey(0)
msk[:, :dw] = 255 msk[:, w-dw:] = 255 return msk def blur_mask(img): assert isinstance(img, numpy.ndarray), 'img_col must be a numpy array' assert img.ndim == 3, 'img_col must be a color image ({0} dimensions currently)'.format(img.ndim) msk, val, blurry = main.blur_detector(img) logger.debug('inverting img_fft') msk = cv2.convertScaleAbs(255-(255*msk/numpy.max(msk))) msk[msk < 50] = 0 msk[msk > 127] = 255 logger.debug('removing border') msk = remove_border(msk) logger.debug('applying erosion and dilation operators') msk = morphology(msk) logger.debug('evaluation complete') result = numpy.sum(msk)/(255.0*msk.size) logger.info('{0}% of input image is blurry'.format(int(100*result))) return msk, result, blurry if __name__ == '__main__': img_path = raw_input("Please Enter Image Path: ") img = cv2.imread(img_path) msk, val = blur_mask(img) scripts.display('img', img) scripts.display('msk', msk) cv2.waitKey(0)
#!/usr/bin/env python # -*- coding: utf-8 -*- __author__ = 'Will Brennan' # Built-in Modules import logging # Standard Modules import cv2 import numpy # Custom Modules import main import scripts if __name__ == '__main__': args = scripts.get_args(from_file=False) logger = scripts.get_logger(quite=args.quite, debug=args.debug) cam = cv2.VideoCapture(0) while True: ret, img_col = cam.read() img_msk = main.process(img_col, args=args) if not args.display: scripts.display('img_col', img_col) scripts.display('img_msk', img_msk) scripts.display('img_skn', cv2.bitwise_and(img_col, img_col, mask=img_msk)) cv2.waitKey(5)