Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,900 changes: 1,900 additions & 0 deletions Detectron2Research.ipynb

Large diffs are not rendered by default.

206 changes: 206 additions & 0 deletions autolabel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import os
import sys
from math import sqrt
from skimage.io import imread
from skimage.feature import blob_dog, blob_log, blob_doh
from skimage.color import rgb2gray
import base64
import pathlib
import json
from PIL import Image
from argparse import ArgumentParser
import matplotlib.pyplot as plt


def main(target_dir_or_file, max_sigma=5, thresh=0.1, pick_index=None, show=True, save=False):
'''This script uses blob detection features of skimage (with parameters set by the user) to
automatically generate annotations for quantum dots in the COCO format. It can operate on
single image files, or recursively operate on directories of images.'''
if os.path.isdir(target_dir_or_file):
process_image_dir(target_dir_or_file, max_sigma, thresh, pick_index, show, save)
elif os.path.isfile(target_dir_or_file):
process_single_file(target_dir_or_file, max_sigma, thresh, pick_index, show, save)
else:
print("invalid image_dir or filepath, please check that this path exists or use the --help flag for usage information.")

def to_single_coco_label(x,y,r):
'''
Takes in circular label information and transforms it into a COCO label in polygon format with a bounding box.

:int x: x-coordinate of circle's center
:int y: y-coordinate of circle's center
:int r: radius of circle

Returns dict object containing a single label in COCO format.
'''
x1, y1 = x-r, y+r # top left
x2, y2 = x+r, y+r # top right
x3, y3 = x-r, y-r # bottom left
x4, y4 = x+r, y-r # bottom right
return {
"segmentation": [[x1,y1,x2,y2,x3,y3,x4,y4]], # list of points in polygon (just a rectangle in this case)
"bbox": [x1,y1,x4,y4], # bounding box in
"group_id": "null",
"shape_type": "polygon",
"flags": {}
}

def to_coco_annotations_file(filepath, labels):
'''
Takes in a single filepath and a list of all labels for it, and
generates a full COCO annotations file for it.

:str filepath: filepath to raw image
:list labels: list of labels (each label generated by the `to_single_coco_label()` function)
'''
with open(filepath,'rb') as f:
img_data = base64.b64encode(f.read()).decode('utf-8')
image = Image.open(filepath)
img_width, img_height = image.size

return {
"version": "4.6.0",
"flags": {},
"annotations": labels,
"imagePath": filepath,
"imageData": img_data,
"imageWidth": img_width,
"imageHeight": img_height
}

def process_image_dir(image_dir: str, max_sigma: float, thresh: float, pick_index: int, show: bool, save: bool):
for curr_dir, next_dirs, files in os.walk(image_dir):
for f in files:
if not f.endswith('.tif'):
continue

filepath = os.path.join(curr_dir, f)
image = image_gray = imread(filepath, as_gray=True)

blobs_log = blob_log(image_gray, max_sigma=max_sigma, num_sigma=10, threshold=thresh)

# Compute radii in the 3rd column.
blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)

blobs_dog = blob_dog(image_gray, max_sigma=max_sigma, threshold=thresh)
blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)

blobs_doh = blob_doh(image_gray, max_sigma=max_sigma, threshold=thresh)

blobs_list = [blobs_log, blobs_dog, blobs_doh]
colors = ['yellow', 'lime', 'red']
titles = ['Laplacian of Gaussian', 'Difference of Gaussian',
'Determinant of Hessian']
sequence = zip(blobs_list, colors, titles)

fig, axes = plt.subplots(1, 3, figsize=(9, 3), sharex=True, sharey=True)
ax = axes.ravel()
labels = []
for idx, (blobs, color, title) in enumerate(sequence):
ax[idx].set_title(title)
ax[idx].imshow(image)
for blob in blobs:
y, x, r = blob
c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)

if idx == pick_index:
label = to_single_coco_label(x, y, r)
labels.append(label)

ax[idx].add_patch(c)
ax[idx].set_axis_off()

if show:
plt.tight_layout()
plt.show()
sys.exit(0)
elif save:
out = to_coco_annotations_file(filepath, labels)
p = pathlib.Path(filepath)
output_path = os.path.join(curr_dir, p.stem + '.json')
with open(output_path, 'w') as f:
json.dump(out, f)
print(f"Saved to {output_path}")

def process_single_file(filepath: str, max_sigma: float, thresh: float, pick_index: int, show: bool, save: bool):
image = image_gray = imread(filepath, as_gray=True)

blobs_log = blob_log(image_gray, max_sigma=max_sigma, num_sigma=10, threshold=thresh)

# Compute radii in the 3rd column.
blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)

blobs_dog = blob_dog(image_gray, max_sigma=max_sigma, threshold=thresh)
blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)

blobs_doh = blob_doh(image_gray, max_sigma=max_sigma, threshold=thresh)

blobs_list = [blobs_log, blobs_dog, blobs_doh]
colors = ['yellow', 'lime', 'red']
titles = ['Laplacian of Gaussian', 'Difference of Gaussian',
'Determinant of Hessian']
sequence = zip(blobs_list, colors, titles)

fig, axes = plt.subplots(1, 3, figsize=(9, 3), sharex=True, sharey=True)
ax = axes.ravel()
labels = []
for idx, (blobs, color, title) in enumerate(sequence):
ax[idx].set_title(title)
ax[idx].imshow(image)
for blob in blobs:
y, x, r = blob
c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)

if idx == pick_index:
label = to_single_coco_label(x, y, r)
labels.append(label)

ax[idx].add_patch(c)
ax[idx].set_axis_off()

# show preview of algos with given parameters on example image
if show:
plt.tight_layout()
plt.show()
sys.exit(0)

# save
elif save:
out = to_coco_annotations_file(filepath, labels)
p = pathlib.Path(filepath)
curr_dir = os.path.dirname(filepath)
output_path = os.path.join(curr_dir, p.stem + '.json')
with open(output_path, 'w') as f:
json.dump(out, f)
print(f"Saved to {output_path}")

if __name__ == '__main__':
parser = ArgumentParser("autolabel-parser", description="""This script uses blob detection features of skimage (with parameters set by the user) to
automatically generate annotations for quantum dots in the COCO format. It can operate on
single image files, or recursively operate on directories of images.""")
parser.add_argument('--target', type=str, required=True, help='image directory or filename')
parser.add_argument('--max_sigma', type=int, default=5, required=False, help='The maximum standard deviation for Gaussian kernel. Keep this high to detect larger blobs. Range of 1-20 recommended.')
parser.add_argument('--threshold', type=float, default=0.1, required=False, help='The absolute lower bound for scale space maxima. Local maxima smaller than threshold are ignored. Reduce this to detect blobs with lower intensities. Range 0.0-0.2 recommended.')
parser.add_argument('--show', action="store_true", help="flag to show preview of all 3 algorithms with the given settings on an example image.")
parser.add_argument('--save', action="store_true", help="flag to use the specified algorithm (LoG, DoG, DoH) to label all images and save labels as JSON files.")
parser.add_argument('--log', action="store_true", help="Laplacian of Gaussian (leftmost image in --show mode")
parser.add_argument('--dog', action="store_true", help="Difference of Gaussian (middle image in --show mode)")
parser.add_argument('--doh', action="store_true", help="Determinant of Hessian (rightmost image in --show mode)")
args = parser.parse_args()
print(f"Autolabel parameters: {args}")

# validate algo if --save specified
pick_index = None
if args.save:
if args.log:
pick_index = 0
elif args.dog:
pick_index = 1
elif args.doh:
pick_index = 2
else:
print("You must choose an algorithm (--log, --dog, or --doh) to save annotations. Use --help for more details.")
sys.exit(0)

# execute script with these params
main(args.target, args.max_sigma, args.threshold, pick_index, args.show, args.save)
20 changes: 20 additions & 0 deletions find_dots4_history.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
python3 find_dots4.py input_dir/32 5 0.1 0 save
python3 find_dots4.py input_dir/106 5 0.2 1 save
python3 find_dots4.py input_dir/106/2a.tif 5 0.1 1 save
python3 find_dots4.py input_dir/106/2b.tif 5 0.1 1 save
python3 find_dots4.py input_dir/106/2c.tif 5 0.1 1 save
python3 find_dots4.py input_dir/106/5a.tif 3 0.05 0 save
python3 find_dots4.py input_dir/107 5 0.1 1 save
python3 find_dots4.py input_dir/107/5a.tif 5 0.1 0 save
python3 find_dots4.py input_dir/132 5 0.1 0 save
python3 find_dots4.py input_dir/157 5 0.1 1 save
python3 find_dots4.py input_dir/157/5a.tif 5 0.05 1 save
python3 find_dots4.py input_dir/404 5 0.1 1 save
python3 find_dots4.py input_dir/405 5 0.1 1 save
python3 find_dots4.py input_dir/406 10 0.1 1 save
python3 find_dots4.py input_dir/86 5 0.2 1 save
python3 find_dots4.py input_dir/86/2n.tif 20 0.1 1 save
python3 find_dots4.py input_dir/86/2o.tif 20 0.1 1 save
python3 find_dots4.py input_dir/86/2p.tif 20 0.2 1 save
python3 find_dots4.py input_dir/87 20 0.15 1 save
python3 find_dots4.py input_dir/87/5a.tif 20 0.1 0 save
21 changes: 21 additions & 0 deletions generate_labels.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
python3 autolabel.py --target="input_dir/32" --max_sigma=5 --threshold=0.1 --log --save &
python3 autolabel.py --target="input_dir/106" --max_sigma=5 --threshold=0.2 --dog --save &
python3 autolabel.py --target="input_dir/106/2a.tif" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/106/2b.tif" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/106/2c.tif" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/106/5a.tif" --max_sigma=3 --threshold=0.05 --log --save &
python3 autolabel.py --target="input_dir/107" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/107/5a.tif" --max_sigma=5 --threshold=0.1 --log --save &
python3 autolabel.py --target="input_dir/132" --max_sigma=5 --threshold=0.1 --log --save &
python3 autolabel.py --target="input_dir/157" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/157/5a.tif" --max_sigma=5 --threshold=0.05 --dog --save &
python3 autolabel.py --target="input_dir/404" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/405" --max_sigma=5 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/406" --max_sigma=10 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/86" --max_sigma=5 --threshold=0.2 --dog --save &
python3 autolabel.py --target="input_dir/86/2n.tif" --max_sigma=20 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/86/2o.tif" --max_sigma=20 --threshold=0.1 --dog --save &
python3 autolabel.py --target="input_dir/86/2p.tif" --max_sigma=20 --threshold=0.2 --dog --save &
python3 autolabel.py --target="input_dir/87" --max_sigma=20 --threshold=0.15 --dog --save &
python3 autolabel.py --target="input_dir/87/5a.tif" --max_sigma=20 --threshold=0.1 --log --save &
1 change: 1 addition & 0 deletions input_dir/106/1a.json

Large diffs are not rendered by default.

Binary file added input_dir/106/1a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/106/1b.json

Large diffs are not rendered by default.

Binary file added input_dir/106/1b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/106/2a.json

Large diffs are not rendered by default.

Binary file added input_dir/106/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/106/2b.json

Large diffs are not rendered by default.

Binary file added input_dir/106/2b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/106/2c.json

Large diffs are not rendered by default.

Binary file added input_dir/106/2c.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/106/5a.json

Large diffs are not rendered by default.

Binary file added input_dir/106/5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/107/1a.json

Large diffs are not rendered by default.

Binary file added input_dir/107/1a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/107/1b.json

Large diffs are not rendered by default.

Binary file added input_dir/107/1b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/107/2a.json

Large diffs are not rendered by default.

Binary file added input_dir/107/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/107/2b.json

Large diffs are not rendered by default.

Binary file added input_dir/107/2b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/107/5a.json

Large diffs are not rendered by default.

Binary file added input_dir/107/5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/132/2a.json

Large diffs are not rendered by default.

Binary file added input_dir/132/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/132/2b.json

Large diffs are not rendered by default.

Binary file added input_dir/132/2b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/132/2c.json

Large diffs are not rendered by default.

Binary file added input_dir/132/2c.tif
Binary file not shown.
Binary file added input_dir/156/1a.tif
Binary file not shown.
Binary file added input_dir/156/1b.tif
Binary file not shown.
Binary file added input_dir/156/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/157/2a.json

Large diffs are not rendered by default.

Binary file added input_dir/157/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/157/5a.json

Large diffs are not rendered by default.

Binary file added input_dir/157/5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/32/5a.json

Large diffs are not rendered by default.

Binary file added input_dir/32/5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/32/5b.json

Large diffs are not rendered by default.

Binary file added input_dir/32/5b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/404/0.5a.json

Large diffs are not rendered by default.

Binary file added input_dir/404/0.5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/404/0.5b.json

Large diffs are not rendered by default.

Binary file added input_dir/404/0.5b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/404/0.5c.json

Large diffs are not rendered by default.

Binary file added input_dir/404/0.5c.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/404/0.5d.json

Large diffs are not rendered by default.

Binary file added input_dir/404/0.5d.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/405/0.5a.json

Large diffs are not rendered by default.

Binary file added input_dir/405/0.5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/405/0.5b.json

Large diffs are not rendered by default.

Binary file added input_dir/405/0.5b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/405/0.5c.json

Large diffs are not rendered by default.

Binary file added input_dir/405/0.5c.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/405/0.5d.json

Large diffs are not rendered by default.

Binary file added input_dir/405/0.5d.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/406/0.5a.json

Large diffs are not rendered by default.

Binary file added input_dir/406/0.5a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/406/0.5b.json

Large diffs are not rendered by default.

Binary file added input_dir/406/0.5b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/406/0.5c.json

Large diffs are not rendered by default.

Binary file added input_dir/406/0.5c.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/406/0.5d.json

Large diffs are not rendered by default.

Binary file added input_dir/406/0.5d.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2a.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2b.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2c.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2c.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2d.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2d.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2e.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2e.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2f.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2f.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2g.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2g.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2h.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2h.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2i.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2i.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2j.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2j.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2k.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2k.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2l.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2l.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2m.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2m.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2n.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2n.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2o.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2o.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2p.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2p.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/86/2q.json

Large diffs are not rendered by default.

Binary file added input_dir/86/2q.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2a.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2a.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2b.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2b.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2c.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2c.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2d.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2d.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2e.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2e.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2f.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2f.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2g.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2g.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2h.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2h.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/2i.json

Large diffs are not rendered by default.

Binary file added input_dir/87/2i.tif
Binary file not shown.
1 change: 1 addition & 0 deletions input_dir/87/5a.json

Large diffs are not rendered by default.

Binary file added input_dir/87/5a.tif
Binary file not shown.
Loading