def preprocess(self, img): """ Gives the final preprocessed version of image. :param img: Input Image :return: img, grayscale, canny and the final binary_img """ img, gray, cleaned, thresh = self.convert_and_threshold_line(img) canny, detected_lines = self.getDetectedLinesCanny(cleaned) if not self.anyDetectedLines(detected_lines): thresh_final = self.process_img_without_lines(255 - gray, canny) else: thresh_final = self.remove_lines_final(thresh, detected_lines) if self.debug: imutils.showImage(thresh_final, "Final Processed Image.") return img, gray, canny, thresh_final
def convert_and_threshold_line(self, img_): """ Takes Image, resizes it, converts to grayscale, cleans with divide tricks and thresholds it with Otsu's Threshold. :param img_: Unprepared Image :return: resized image, grayscale, cleaned image with divide trick, thresholded image. """ img_ = cv2.resize(img_, (self.width, self.height), interpolation=cv2.INTER_NEAREST) gray = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY) cleaned = cv2.GaussianBlur(gray, (51, 51), 0) cleaned = cv2.divide(gray, cleaned, scale=255) if self.debug: imutils.showImage(cleaned, "After Divide Trick") thresh = cv2.threshold(cleaned, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] if self.debug: imutils.showImage(thresh, "After Otsu's Thresholding on Divided") return img_, gray, cleaned, thresh
def remove_lines_final(self, thresh, detected_lines): """ Remove given lines from the given thresholded image, clean and repair. :param thresh: The thresholded image containing numbers and lines. :param detected_lines: Binary image containing only lines. :return: Thresholded Binary Image after removing lines, cleaning and repairing. """ thresh[detected_lines > 0] = 0 if self.debug: imutils.showImage(thresh, "Remove Lines") thresh = cv2.medianBlur(thresh, 3) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 5)) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=3) if self.debug: imutils.showImage(thresh, "Final Image after Removing Lines") return thresh
def getDetectedLinesCanny(self, cleaned): """ Takes image (cleaned after divide trick) and detects lines using Canny, contours and then morphing open. :param cleaned: cleaned input image :return: image after applying canny and binary detected lines. """ v = np.median(cleaned) sigma = 0.33 lower_thresh = int(max(0, (1.0 - sigma) * v)) upper_thresh = int(min(255, (1.0 + sigma) * v)) canny = cv2.Canny(cleaned, lower_thresh, upper_thresh) cnts, _ = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if self.debug: imutils.showImage(canny, "Canny") kern_width = 20 new = np.zeros_like(canny) cv2.drawContours(new, cnts, -1, 255, 2) new = cv2.erode(new, (6, 2), iterations=2) if self.debug: imutils.showImage(new, "Contours on Canny") horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kern_width, 1)) vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kern_width * 4)) detected_lines = cv2.morphologyEx( new, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) + cv2.morphologyEx( new, cv2.MORPH_OPEN, vertical_kernel, iterations=2) if self.debug: imutils.showImage(detected_lines, "Detected on Canny Contours(R)") return canny, detected_lines
roi = np.expand_dims(roi, axis=0) notSmiling, smiling = model.predict(roi)[0] label = "Smiling" if smiling > notSmiling else "Not Smiling" textpos = (fX, fY - 10) if fY < 30: if fY + fH < height - 40: textpos = (fX, fY + fH + 20) elif fX > 50: textpos = (0, fY) else: textpos = (fX + fW + 10, fY) cv2.putText(img_clone, f"{label}: {max(notSmiling, smiling) * 100}%", textpos, cv2.FONT_HERSHEY_SIMPLEX, 0.45, (20, 255, 15), 1) cv2.rectangle(img_clone, (fX, fY), (fX + fW, fY + fH), (20, 255, 15), 2) imutils.showImage(img_clone, "Prediction") else: if args["video"]: cap = cv2.VideoCapture(args["video"]) else: cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if args["video"] and not ret: break img = frame height, width = img.shape[:2] if width > 750 or width < 150: img = imutils.resize(img, width=600) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)