<jupyter_start><jupyter_text>Algorithm step-by-step visual explanation<jupyter_code>import matplotlib.pyplot as plt
import random

from daugman_visual_explanation import DaugmanVisualExplanation
from daugman import find_iris
# fixed size for matplotlib output
plt.rcParams['figure.figsize'] = [5, 5]
# for replicability
random.seed(2020)

dve = DaugmanVisualExplanation('eye.jpg')<jupyter_output><empty_output><jupyter_text>The Daugman's part Daugman algorithm measures the difference in average pixel intensities on a grayscale image for a bunch of circles with the same center and different radius.The idea is to find the biggest drop in intensity values between two neighbor circles. It should imply the transition between the iris and its surroundings.E.g., on the below image, yellow, green, and red circles have the same pixel intensities because all pixels underneath are black. Thus deltas (difference) between all those intensities are 0 (yellow-green, green-red). But pixels under the blue circle are all white, so the red-blue difference is the highest, which means that the red circle is the best guess for the iris border. In case we had not a red circle, the green-blue difference would have the highest difference, thus the green circle would have been chosen.Ideally, for best accuracy, the step between circles radii should be 1px.<jupyter_code>dve.plot_pixel_intensity_delta_pic()<jupyter_output><empty_output><jupyter_text>Also, it is not hard to see that the central point selection is very important and for best accuracy, we need to check every single point on the image. It is computationally expensive, so we need to find a way to reduce the number of potential points.One more thing: to avoid false-positive results, the algorithm applies a GaussianBlur filter on all collected deltas for a single potential iris center, it reduces noise and makes results smoother.  Find iris part In order to reduce the number of potential points, we will imply, that the iris cannot be larger than 1/3 of the image side if the eye is properly cropped.So, we do not have to check every pixel on the image, only those, which are in the central 1/3 of the image:```0 0 00 1 00 0 0```For each of these dots, we will need to run the Daugman algorithm. In this example, we will take only every 3rd point for clarity. Thereby we will have x3 speed up, with slightly lower accuracy.<jupyter_code># plot all potential iris centers
img_dot = dve.plot_all_potential_iris_centers()<jupyter_output><empty_output><jupyter_text>Also, we presume, that iris could not be less than a circle with a certain radius, let's say 10px, and also it could not be more than a certain radius, let's say 30px.Now for each circle between min and max radius with the step 2px, we will take all pixel values and sum them up.We selected 2px radii step for plotting clarity.<jupyter_code>img_circles = dve.plot_circles_for_one_center(img_dot, dot_idx=0)<jupyter_output><empty_output><jupyter_text>Daugman will find the best iris candidate among those circles, for that point<jupyter_code>_ = dve.plot_best_circle_for_a_few_potential_iris_centers(img_dot, [0])<jupyter_output><empty_output><jupyter_text>Let's do the same thing for every 20th potential iris point<jupyter_code># plot best circle for every 20th potential iris center
_ = dve.plot_best_circle_for_a_few_potential_iris_centers(img_dot, range(0, len(dve.all_points), 20))<jupyter_output><empty_output><jupyter_text>And now for each potential point. The resulting image is hard to perceive, but the best iris candidate will be selected among plotted circles.<jupyter_code># plot best circle for every 20th potential iris center
_ = dve.plot_best_circle_for_a_few_potential_iris_centers(img_dot, range(0, len(dve.all_points)))<jupyter_output><empty_output><jupyter_text>It will be the circle with the highest value (biggest delta). With selected parameters, it would be the result below:<jupyter_code>_ = dve.find_iris(daugman_start=10, daugman_end=30, daugman_step=2, points_step=3)<jupyter_output><empty_output><jupyter_text>If we only change the radii step from 2px to 1px, we will get a better result but x2 slower:<jupyter_code>_ = dve.find_iris(daugman_start=10, daugman_end=30, daugman_step=1, points_step=3)<jupyter_output><empty_output><jupyter_text>The most computationally expensive and potentially most accurate variant:<jupyter_code>_ = dve.find_iris(daugman_start=10, daugman_end=50, daugman_step=1, points_step=1)<jupyter_output><empty_output><jupyter_text>PlaygroundPlay with parameters to get an intuition<jupyter_code>dve.find_iris_on_binary_image(daugman_start=10, daugman_end=30, daugman_step=2, points_step=1)
dve.find_iris_on_binary_image(daugman_start=10, daugman_end=30, daugman_step=1, points_step=10)
dve.find_iris_on_binary_image(daugman_start=10, daugman_end=30, daugman_step=10, points_step=1)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06299856821435876, 'fraction_numerical': 0.016772346083043566, 'mean_word_length': 6.712933753943218, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '354259', 'license': 'MIT', 'n_tokens_mistral': 1587, 'n_tokens_neox': 1492, 'n_words': 567, 'path': 'daugman_visual_explanation.ipynb', 'repo_name': 'banderlog/daugman', 'size': '4889'}