<jupyter_start><jupyter_text>Detecting low emissivity spots on copper grains imagesThis demo compares different blob detection algorithms included in theScikit-image library.The goal of the comparison it to find the most suitable way to detect and trackthe low emissivity spots on thermal images of copper grains.The number of detected spots is a feature that characterizes different classesof copper grains.<jupyter_code>from math import sqrt

import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage.feature import blob_dog, blob_log, blob_doh
from skimage.io import imread

from img_processing import crop_ui, full_prepare


%matplotlib inline
%config InlineBackend.figure_format = 'retina'<jupyter_output><empty_output><jupyter_text>Comparison function and description of given methods of blob detectionThe comparison function receives an image and detects blobs on it utilizingthree alternative methods.The first one `blob_log` is based on *Laplacian of Gaussian*.According to the description provided by the library documentation it is themost accurate and slowest one.It calculates Gaussian of the image using various standard deviations and thencomputes its Laplacians that are stacked in a cube.The bright spots in the cube represent the maxims on the images, that means theblobs.This method is especially slow when detecting large blobs when the computationsare time consuming.The second one, that is based on *difference of Gaussain* implemented as`blobs_dog` is faster version of the first algorithm.It computes simple *difference of Gaussian* instead of calculating derivatives.The last function the `blobs_doh` is based on *determinant of Hessian*.Hessian is a matrix of all second derivatives of a function.The last algorithm is the fastest one, but it may fail to detect small blobs.All functions take `threshold` parameter that determines their sensitivity.The smaller it is the more likely it is that a group of pixels will be detectedas a blob.With a `threshold` of 0.125 the first two algorithms happen to detect blobswhereas the last function needs a threshold of 0.01 to find any blobs.If all functions are given the same `threshold` the *Laplacian of Gaussian*detects the largest number of blobs.The second parameter `max_sigma` limits the size of detected blobs.Because the spots with low emissivity are rather small, it is crucial to limitthis parameter.The `blob_log` takes additional parameter `num_sigma` tells the function thenumber of standard deviations for which the Gaussian of the image should becalculated.<jupyter_code>def compare_detection(img):
    '''
    Detect blobs in thermal images of grains using three methods
    and numbers of blobs.
    '''
    blobs_log = blob_log(img, max_sigma=2, num_sigma=10, threshold=.125)
    blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)

    blobs_dog = blob_dog(img, max_sigma=2, threshold=.125)
    blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)

    blobs_doh = blob_doh(img, max_sigma=2, threshold=.01)
    blobs_doh[:, 2] = blobs_doh[:, 2] * sqrt(2)

    return [blobs_log, blobs_dog, blobs_doh]<jupyter_output><empty_output><jupyter_text>Plotting the comparisonWe will load and prepare sample image, that will be used compare blob detectionalgorithms.A second cropped image is also needed for plotting the comparison.<jupyter_code>sample_img = imread('img/104_E5R_0.jpg')
img_crop = crop_ui(rgb2gray(sample_img))
img_prep = full_prepare(sample_img)<jupyter_output><empty_output><jupyter_text>Now we call the comparison function on the prepared image.It will return a list containing blobs detected on images using differentmethods.<jupyter_code>blob_list = compare_detection(img_prep)<jupyter_output><empty_output><jupyter_text>At last we can plot the comparison on subplots and show number of detected blobsin the titles.<jupyter_code>titles = ('Laplacian of Gaussian', 'Difference of Gaussian',
          'Determinant of Hessian')

fig, axes = plt.subplots(1, 3, figsize=(13, 4))
ax = axes.ravel()
loop_set = zip(blob_list, colors, titles)
for idx, (blobs, color, title) in enumerate(loop_set):
    ax[idx].set_title('{}, number of blobs: {}'.format(title, len(blobs)))
    ax[idx].imshow(img_crop, cmap=plt.get_cmap('gray'))
    for blob in blobs:
        y, x, r = blob
        c = plt.Circle((x, y), r, color='r', linewidth=1, fill=False)
        ax[idx].add_patch(c)

plt.tight_layout()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07038123167155426, 'fraction_numerical': 0.009474396571170765, 'mean_word_length': 5.444767441860465, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, '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': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '392959', 'license': 'MIT', 'n_tokens_mistral': 1333, 'n_tokens_neox': 1247, 'n_words': 517, 'path': 'blob_detection_methods.ipynb', 'repo_name': 'MaciejZj/Copper-grains-classification', 'size': '4433'}