def __init__(self, image_folder, filterchain): self.image_folder = ImageFolder() self.image_folder.return_file_name = True self.image_folder.read_folder(image_folder) self.chain = chain.read(filterchain) self.precisions = {} self.noises = {}
class LineTest: def __init__(self, image_folder, filterchain): self.image_folder = ImageFolder() self.image_folder.return_file_name = True self.image_folder.read_folder(image_folder) self.chain = chain.read(filterchain) self.precisions = {} self.noises = {} def launch(self): for file_name, image in self.image_folder: if os.path.exists(file_name + '.map'): filtered = self.chain.execute(image) filtered = self.make_binary_array(filtered) map = np.fromfile(file_name + '.map', dtype=np.uint8) map = map.reshape(filtered.shape) self.precisions[file_name] = self.find_precision(filtered, map) self.noises[file_name] = self.find_noise(filtered, map) def make_binary_array(self, filtered): gray = cv2.cvtColor(filtered, cv.CV_BGR2GRAY) bin = np.zeros(gray.shape, dtype=np.uint8) bin[gray > 0] = 255 return bin def find_precision(self, filtered, map): undetected = (filtered & np.invert(map)) sum_map = np.count_nonzero(map) sum_undetected = np.count_nonzero(undetected) return (sum_map - sum_undetected) / float(sum_map) def remove_line(self, filtered, map): detected = (filtered & map) return (filtered & np.invert(detected)) def find_noise(self, filtered, map): filtered = self.remove_line(filtered, map) cnt_filtered, _ = cv2.findContours(filtered, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnt_map, _ = cv2.findContours(map, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) noise = 0 for cf in cnt_filtered: dist = abs(self.find_dist_between_blob_and_line(cf, cnt_map)) area = np.abs(cv2.contourArea(cf)) noise += dist * area return noise / self.max_noise(cnt_map, filtered.shape) def max_noise(self, cnt_map, image_size): max_dist = math.sqrt(image_size[0]**2 + image_size[1]**2) / 4.0 max_noise = 0 for cm in cnt_map: area = np.abs(cv2.contourArea(cm)) / 2.0 max_noise += area * max_dist return max_noise def find_dist_between_blob_and_line(self, cf, cnt_map): moment = cv2.moments(cf) m00 = moment['m00'] if m00 <> 0: x = int(moment['m10'] / m00) y = int(moment['m01'] / m00) else: x = cf[0][0][0] y = cf[0][0][1] min_dist = sys.maxint for cm in cnt_map: dist = cv2.pointPolygonTest(cm, (x, y), True) if dist < min_dist: min_dist = dist return min_dist def total_images(self): count = 0 for f in self.image_folder.file_names: map = f + '.map' if os.path.exists(map): count += 1 return count def avg_noise(self): c = len(self.noises.values()) s = sum(self.noises.values()) return s / c def avg_precision(self): c = len(self.precisions.values()) s = sum(self.precisions.values()) return s / c