Package: camtrapml
CamTrapMLCamTrapML is a Python library for Detecting, Classifying, and Analysing WildlifeCamera TrapImagery.Installation$ pip install camtrapmlFeaturesLoading DataSearch for images in a directory, load an image and create a thumbnail.%load_extautoreload%autoreloadfromcamtrapml.datasetimportImageDatasetfromcamtrapml.image.utilsimportload_image,thumbnailimageset=ImageDataset(name="Test Images",path="test/fixtures/images",)image_paths=list(imageset.enumerate_images())thumbnail(load_image(image_paths[0]))EXIF ExtractionEXIF extraction is a common task in gathering the metadata such as each image's timestamp, camera model, focal length, etc. Some researchers write labelling into the EXIF data. CamTrapML doesn't assist with writing to EXIF. However, there is functionality for extracting it for analysis and building datasets for training new models from previously labelled images.ExifTool is required for this package to work. Installation instructions can be foundhere.Three methods are available for extracting EXIF data from images. Each with different performance characteristics.Method 1: Individual Imagesfromcamtrapml.image.exifimportextract_exifexif=extract_exif(image_paths[0])exifMethod 2: Multiple Imagesextract_multiple_exifpasses a list of image paths to ExifTool and returns a list of dictionaries containing the EXIF data. This is faster thanextract_exifwhen multiple images are being processed as it only passes the list of image paths to ExifTool once, rather than spawning a new process for each image.fromcamtrapml.image.exifimportextract_multiple_exifexif=extract_multiple_exif(image_paths)exif[0]Method 3: Multiple Images, Multiple ProcessesWhen processing large datasets, it's apparent that the bottleneck in extracting the EXIF information tends to be the CPU. This method spawns multiple versions of ExifTool in parallel, each with a batch of image paths. This is faster thanextract_multiple_exifwhen processing large datasets as it allows for multiple processes to be spawned and the data extracted in parallel.fromcamtrapml.image.exifimportextract_multiple_exif_fastexif=extract_multiple_exif_fast(image_paths)exif[0]DetectionVarious Detection models are available in thecamtrapml.detectionsubpackage. These currently include MegaDetector (v4.1, v3 and v2) and support for loading in custom Tensorflow v1.x Object Detection Frozen models.Detection with MegaDetector v4.1fromcamtrapml.detection.models.megadetectorimportMegaDetectorV4_1fromcamtrapml.detection.utilsimportrender_detectionswithMegaDetectorV4_1()asdetector:detections=detector.detect(image_paths[0])thumbnail(render_detections(image_paths[0],detections,class_map=detector.class_map))Detection with a custom Tensorflow v1.x Object Detection Frozen model!cp~/.camtrapml/models/megadetector/v4.1.0/md_v4.1.0.pbexample-custom-model.pbfromcamtrapml.detection.models.tensorflowimportTF1ODAPIFrozenModelfromcamtrapml.detection.utilsimportrender_detectionsfrompathlibimportPathwithTF1ODAPIFrozenModel(model_path=Path("example-custom-model.pb").expanduser(),class_map={1:"animal",},)asdetector:detections=detector.detect(image_paths[1])thumbnail(render_detections(image_paths[1],detections,class_map=detector.class_map))Extract Detectionsfromcamtrapml.detection.models.megadetectorimportMegaDetectorV4_1fromcamtrapml.detection.utilsimportextract_detections_from_imagewithMegaDetectorV4_1()asdetector:detections=detector.detect(image_paths[0])list(extract_detections_from_image(load_image(image_paths[0]),detections))[0]Remove Humans from ImagesIn order to reduce the risks of identification of humans in line with GDPR, CamTrapML provides the ability to remove humans from images. This is achieved by using the MegaDetector v3+ models to detect humans in the image, and then replacing all pixels in each human detection.fromcamtrapml.detection.models.megadetectorimportMegaDetectorV4_1fromcamtrapml.detection.utilsimportremove_detections_from_imagefromcamtrapml.image.utilsimportload_image,thumbnailfrompathlibimportPathct_image_with_humans=Path("test/fixtures/human_images/IMG_0254.JPG").expanduser()withMegaDetectorV4_1()asdetector:detections=detector.detect(ct_image_with_humans)human_class_id=2thumbnail(remove_detections_from_image(load_image(ct_image_with_humans),[detectionfordetectionindetectionsifdetection["category"]==human_class_idanddetection["conf"]>0.5],))