Skip to content

Commit ed0f519

Browse files
authored
Merge pull request #50 from WEHI-ResearchComputing/45-mrc-compatibility-when-not-using-denoiser
Add MRC Input Compatibility When Not Using Denoiser Closes #45 TO-DO Review raw MRC detection weights to ensure optimal performance when not using denoiser: https://huggingface.co/MihinP/PartiNet
2 parents d20fd6a + 1cfa808 commit ed0f519

5 files changed

Lines changed: 40 additions & 7 deletions

File tree

Singularity

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ from: python:3.9.19-slim-bookworm
1818
%labels
1919
AUTHORS Mihin Perera, Edward Yang, Julie Iskander
2020
MAINTAINERS Mihin Perera, Edward Yang, Julie Iskander
21-
VERSION v0.2.0
21+
VERSION v1.0.0

partinet/DynamicDet/detect.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
sys.stdout.reconfigure(line_buffering=True)
4242
sys.stderr.reconfigure(line_buffering=True)
4343

44+
# helper ----------------------------------------------------------------
45+
def _save_filename(p: Path) -> str:
46+
"""Return an output filename for image `p`.
47+
48+
Currently we cannot write `.mrc` files with OpenCV, so convert any
49+
input with that suffix to PNG. Other extensions are returned as-is.
50+
"""
51+
if p.suffix.lower() == '.mrc':
52+
return p.stem + '.png'
53+
return p.name
54+
4455
# --- Detection function ---
4556
def detect(opt, save_img=False):
4657
source, cfg, weight, view_img, save_txt, nc, imgsz = (
@@ -145,7 +156,8 @@ def worker(device):
145156
p, s, im0, f_idx = path, '', im0s, frame
146157

147158
p = Path(p)
148-
save_path = str(save_dir / p.name)
159+
# choose image-filename for saving; helper contains mrc logic
160+
save_path = str(save_dir / _save_filename(p))
149161
txt_path = str(save_dir / 'labels' / p.stem) + ('' if dataset.mode == 'image' else f'_{f_idx}')
150162
gn = torch.tensor(im0.shape)[[1, 0, 1, 0]]
151163

partinet/DynamicDet/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import partinet.DynamicDet
1515
from partinet.DynamicDet.models.yolo import Model
16-
from partinet.DynamicDet.utils.datasets import create_dataloader
16+
from partinet.DynamicDet.utils.datasets import create_dataloader, LoadImages
1717
from partinet.DynamicDet.utils.general import coco80_to_coco91_class, check_dataset, check_file, check_img_size, \
1818
box_iou, non_max_suppression, scale_coords, xyxy2xywh, xywh2xyxy, set_logging, increment_path, colorstr
1919
from partinet.DynamicDet.utils.metrics import ap_per_class, ConfusionMatrix

partinet/DynamicDet/utils/datasets.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from PIL import Image, ExifTags
2020
from torch.utils.data import Dataset
2121
from tqdm import tqdm
22+
import mrcfile # support cryoEM micrograph format
2223

2324
import pickle
2425
from copy import deepcopy
@@ -29,10 +30,14 @@
2930
from partinet.DynamicDet.utils.general import check_requirements, xyxy2xywh, xywh2xyxy, xywhn2xyxy, xyn2xy, segment2box, segments2boxes, \
3031
resample_segments, clean_str
3132
from partinet.DynamicDet.utils.torch_utils import torch_distributed_zero_first
33+
from partinet.process_utils.guided_denoiser import transform
3234

3335
# Parameters
3436
help_url = 'https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data'
35-
img_formats = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'dng', 'webp', 'mpo'] # acceptable image suffixes
37+
# acceptable image suffixes (extensions are compared case‑insensitively)
38+
# add 'mrc' so that LoadImages/LoadImagesAndLabels can see micrographs directly
39+
# micrographs are read with `mrcfile`; only uncompressed MRC files are supported
40+
img_formats = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'dng', 'webp', 'mpo', 'mrc']
3641
vid_formats = ['mov', 'avi', 'mp4', 'mpg', 'mpeg', 'm4v', 'wmv', 'mkv'] # acceptable video suffixes
3742
logger = logging.getLogger(__name__)
3843

@@ -137,6 +142,7 @@ def __init__(self, path, img_size=640, stride=32):
137142
else:
138143
raise Exception(f'ERROR: {p} does not exist')
139144

145+
# allow uncompressed .mrc files
140146
images = [x for x in files if x.split('.')[-1].lower() in img_formats]
141147
videos = [x for x in files if x.split('.')[-1].lower() in vid_formats]
142148
ni, nv = len(images), len(videos)
@@ -183,7 +189,15 @@ def __next__(self):
183189
else:
184190
# Read image
185191
self.count += 1
186-
img0 = cv2.imread(path) # BGR
192+
# support cryo-EM micrographs saved as MRC
193+
if path.lower().endswith('.mrc'):
194+
img_mrc = mrcfile.read(path)
195+
img0 = transform(img_mrc).astype(np.uint8)
196+
# `transform` returns a single-channel image; networks expect BGR
197+
if img0.ndim == 2:
198+
img0 = cv2.cvtColor(img0, cv2.COLOR_GRAY2BGR)
199+
else:
200+
img0 = cv2.imread(path) # BGR
187201
assert img0 is not None, 'Image Not Found ' + path
188202
#print(f'image {self.count}/{self.nf} {path}: ', end='')
189203

@@ -668,7 +682,14 @@ def load_image(self, index):
668682
img = self.imgs[index]
669683
if img is None: # not cached
670684
path = self.img_files[index]
671-
img = cv2.imread(path) # BGR
685+
# support uncompressed mrc micrographs
686+
if path.lower().endswith('.mrc'):
687+
img_mrc = mrcfile.read(path)
688+
img = transform(img_mrc).astype(np.uint8)
689+
if img.ndim == 2:
690+
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
691+
else:
692+
img = cv2.imread(path) # BGR
672693
assert img is not None, 'Image Not Found ' + path
673694
h0, w0 = img.shape[:2] # orig hw
674695
r = self.img_size / max(h0, w0) # resize image to img_size

partinet/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import click
22
import sys, os
33

4-
__version__ = "0.2.0"
4+
__version__ = "1.0.0"
55

66
DYNAMICDET_AVAILABLE_MODELS = ["yolov7", "yolov7x", "yolov7-w6", "yolov7-e6", "yolov7-d6", "yolov7-e6e"]
77

0 commit comments

Comments
 (0)