Merge pull request #1833 from pierotofy/dng

DNG/RAW/NEF file support
pull/1835/head
Piero Toffanin 2025-02-24 23:26:46 -05:00 zatwierdzone przez GitHub
commit ce839d439a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
13 zmienionych plików z 72 dodań i 34 usunięć

Wyświetl plik

@ -21,7 +21,7 @@ The easiest way to run ODM is via docker. To install docker, see [docs.docker.co
docker pull opendronemap/odm
```
Run ODM by placing some images (JPEGs or TIFFs) in a folder named “images” (for example `C:\Users\youruser\datasets\project\images` or `/home/youruser/datasets/project/images`) and simply run from a Command Prompt / Terminal:
Run ODM by placing some images (JPEGs, TIFFs or DNGs) in a folder named “images” (for example `C:\Users\youruser\datasets\project\images` or `/home/youruser/datasets/project/images`) and simply run from a Command Prompt / Terminal:
```bash
# Windows

Wyświetl plik

@ -244,7 +244,7 @@ externalproject_add(dem2points
externalproject_add(odm_orthophoto
DEPENDS opencv
GIT_REPOSITORY https://github.com/OpenDroneMap/odm_orthophoto.git
GIT_TAG 353
GIT_TAG 355
PREFIX ${SB_BINARY_DIR}/odm_orthophoto
SOURCE_DIR ${SB_SOURCE_DIR}/odm_orthophoto
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${SB_INSTALL_DIR}

Wyświetl plik

@ -53,7 +53,7 @@ ExternalProject_Add(${_proj_name}
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
GIT_REPOSITORY https://github.com/OpenDroneMap/openMVS
GIT_TAG 320
GIT_TAG 355
#--Update/Patch step----------
UPDATE_COMMAND ""
#--Configure step-------------

Wyświetl plik

@ -25,7 +25,7 @@ ExternalProject_Add(${_proj_name}
#--Download step--------------
DOWNLOAD_DIR ${SB_DOWNLOAD_DIR}
GIT_REPOSITORY https://github.com/OpenDroneMap/OpenSfM/
GIT_TAG 352
GIT_TAG 355
#--Update/Patch step----------
UPDATE_COMMAND git submodule update --init --recursive
#--Configure step-------------

Wyświetl plik

@ -1 +1 @@
3.5.4
3.5.5

Wyświetl plik

@ -4,6 +4,24 @@ from opendm import log
import zipfile
import time
import sys
import rawpy
def read_image(img_path):
if img_path[-4:].lower() in [".dng", ".raw", ".nef"]:
try:
with rawpy.imread(img_path) as r:
img = r.postprocess(output_bps=8, use_camera_wb=True, use_auto_wb=False)
except:
return None
else:
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
if img is None:
return None
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
return img
def get_model(namespace, url, version, name = "model.onnx"):
version = version.replace(".", "_")

Wyświetl plik

@ -5,6 +5,7 @@ import cv2
import os
import onnxruntime as ort
from opendm import log
from opendm.ai import read_image
from threading import Lock
mutex = Lock()
@ -73,11 +74,7 @@ class BgFilter():
return output
def run_img(self, img_path, dest):
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
if img is None:
return None
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = read_image(img_path)
mask = self.get_mask(img)
img_name = os.path.basename(img_path)

Wyświetl plik

@ -40,7 +40,7 @@ odm_orthophoto_path = os.path.join(superbuild_bin_path, "odm_orthophoto")
settings_path = os.path.join(root_path, 'settings.yaml')
# Define supported image extensions
supported_extensions = {'.jpg','.jpeg','.png', '.tif', '.tiff', '.bmp'}
supported_extensions = {'.jpg','.jpeg','.png', '.tif', '.tiff', '.bmp', '.raw', '.dng', '.nef'}
supported_video_extensions = {'.mp4', '.mov', '.lrv', '.ts'}
# Define the number of cores

Wyświetl plik

@ -1,6 +1,6 @@
from PIL import Image
import cv2
import rawpy
from opendm import log
Image.MAX_IMAGE_PIXELS = None
@ -9,12 +9,18 @@ def get_image_size(file_path, fallback_on_error=True):
"""
Return (width, height) for a given img file
"""
try:
with Image.open(file_path) as img:
width, height = img.size
if file_path[-4:].lower() in [".dng", ".raw", ".nef"]:
with rawpy.imread(file_path) as img:
s = img.sizes
width, height = s.raw_width, s.raw_height
else:
with Image.open(file_path) as img:
width, height = img.size
except Exception as e:
if fallback_on_error:
log.ODM_WARNING("Cannot read %s with PIL, fallback to cv2: %s" % (file_path, str(e)))
log.ODM_WARNING("Cannot read %s with image library, fallback to cv2: %s" % (file_path, str(e)))
img = cv2.imread(file_path)
width = img.shape[1]
height = img.shape[0]

Wyświetl plik

@ -273,7 +273,10 @@ def compute_band_maps(multi_camera, primary_band):
# Quick check
if filename_without_band == p.filename:
raise Exception("Cannot match bands by filename on %s, make sure to name your files [filename]_band[.ext] uniformly." % p.filename)
if not filename_without_band in filename_map:
raise Exception("Cannot match bands by filename on %s, make sure to name your files [filename]_band[.ext] uniformly, check that your images have the appropriate CaptureUUID XMP tag and that no images are missing." % p.filename)
s2p[p.filename] = filename_map[filename_without_band]
if band['name'] != band_name:

Wyświetl plik

@ -43,33 +43,49 @@ def generate_png(orthophoto_file, output_file=None, outsize=None):
output_file = base + '.png'
# See if we need to select top three bands
bandparam = ""
params = []
gtif = gdal.Open(orthophoto_file)
if gtif.RasterCount > 4:
try:
gtif = gdal.Open(orthophoto_file)
bands = []
for idx in range(1, gtif.RasterCount+1):
bands.append(gtif.GetRasterBand(idx).GetColorInterpretation())
bands = dict(zip(bands, range(1, len(bands)+1)))
try:
if gtif.RasterCount >= 3:
red = bands.get(gdal.GCI_RedBand)
green = bands.get(gdal.GCI_GreenBand)
blue = bands.get(gdal.GCI_BlueBand)
if red is None or green is None or blue is None:
raise Exception("Cannot find bands")
params.append("-b %s -b %s -b %s" % (red, green, blue))
else:
params.append("-b 1 -b 2 -b 3")
elif gtif.RasterCount <= 2:
params.append("-b 1")
alpha = bands.get(gdal.GCI_AlphaBand)
if alpha is not None:
params.append("-b %s" % alpha)
else:
params.append("-a_nodata 0")
bandparam = "-b %s -b %s -b %s -a_nodata 0" % (red, green, blue)
except:
bandparam = "-b 1 -b 2 -b 3 -a_nodata 0"
gtif = None
dtype = gtif.GetRasterBand(1).DataType
if dtype != gdal.GDT_Byte:
params.append("-ot Byte")
if gtif.RasterCount >= 3:
params.append("-scale_1 -scale_2 -scale_3")
elif gtif.RasterCount <= 2:
params.append("-scale_1")
gtif = None
except Exception as e:
log.ODM_WARNING("Cannot read orthophoto information for PNG generation: %s" % str(e))
osparam = ""
if outsize is not None:
osparam = "-outsize %s 0" % outsize
params.append("-outsize %s 0" % outsize)
system.run('gdal_translate -of png "%s" "%s" %s %s '
'--config GDAL_CACHEMAX %s%% ' % (orthophoto_file, output_file, osparam, bandparam, get_max_memory()))
system.run('gdal_translate -of png "%s" "%s" %s '
'--config GDAL_CACHEMAX %s%% ' % (orthophoto_file, output_file, " ".join(params), get_max_memory()))
def generate_kmz(orthophoto_file, output_file=None, outsize=None):
if output_file is None:

Wyświetl plik

@ -6,6 +6,7 @@ import os
import onnxruntime as ort
from .guidedfilter import guided_filter
from opendm import log
from opendm.ai import read_image
from threading import Lock
mutex = Lock()
@ -72,11 +73,7 @@ class SkyFilter():
def run_img(self, img_path, dest):
img = cv2.imread(img_path, cv2.IMREAD_COLOR)
if img is None:
return None
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = read_image(img_path)
img = np.array(img / 255., dtype=np.float32)
mask = self.get_mask(img)

Wyświetl plik

@ -23,6 +23,7 @@ rasterio==1.2.3 ; sys_platform == 'linux'
rasterio==1.3.6 ; sys_platform == 'darwin'
https://github.com/OpenDroneMap/windows-deps/raw/main/rasterio-1.2.3-cp38-cp38-win_amd64.whl ; sys_platform == 'win32'
https://github.com/OpenDroneMap/windows-deps/raw/main/GDAL-3.2.3-cp38-cp38-win_amd64.whl ; sys_platform == 'win32'
odmrawpy==0.24.1
repoze.lru==0.7
scikit-learn==1.1.1
Pywavelets==1.3.0