Skip to content

Commit

Permalink
Wrappers: Add method to load image from file
Browse files Browse the repository at this point in the history
Adds `zivid.Image.load` method that creates a `zivid.Image` by reading
data from an image file. Supported image file formats are PNG, JPEG and
BMP. Uses `Zivid::Image<PixelFormat>(const std::string& fileName)`
constructor from zivid-sdk 2.11.
  • Loading branch information
vawale committed Dec 14, 2023
1 parent 01226d9 commit 6c983b6
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 4 deletions.
30 changes: 30 additions & 0 deletions modules/zivid/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,36 @@ def save(self, file_path):
"""
self.__impl.save(str(file_path))

@classmethod
def load(cls, file_path, color_format):
r"""Load an image from a file.
The supported file types are PNG (.png), JPEG (.jpg, .jpeg), and BMP (.bmp). This method
will throw an exception if it fails to load the provided file_path.
Supported color formats:
rgba: ndarray(Height,Width,4) of uint8
bgra: ndarray(Height,Width,4) of uint8
srgb: ndarray(Height,Width,4) of uint8
Args:
file_path: A pathlib.Path instance or a string specifying file path to load
color_format: A string specifying color format to load
"""
supported_color_formats = {
"rgba": _zivid.ImageRGBA,
"bgra": _zivid.ImageBGRA,
"srgb": _zivid.ImageSRGB,
}
if color_format not in supported_color_formats:
raise ValueError(
"Unsupported color format: {color_format}. Supported formats: {all_formats}".format(
color_format=color_format, all_formats=list(supported_color_formats.keys())
)
)
color_format_class = supported_color_formats[color_format]
return Image(color_format_class(str(file_path)))

def copy_data(self):
"""Copy image data to numpy array.
Expand Down
9 changes: 6 additions & 3 deletions src/ReleasableImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,25 @@ namespace ZividPython
pyClass.def_buffer(imageRGBADataBuffer)
.def("save", &ReleasableImageRGBA::save, py::arg("file_name"))
.def("width", &ReleasableImageRGBA::width)
.def("height", &ReleasableImageRGBA::height);
.def("height", &ReleasableImageRGBA::height)
.def(py::init<const std::string &>(), "Load image from file");
}

void wrapClass(pybind11::class_<ReleasableImageBGRA> pyClass)
{
pyClass.def_buffer(imageBGRADataBuffer)
.def("save", &ReleasableImageBGRA::save, py::arg("file_name"))
.def("width", &ReleasableImageBGRA::width)
.def("height", &ReleasableImageBGRA::height);
.def("height", &ReleasableImageBGRA::height)
.def(py::init<const std::string &>(), "Load image from file");
}

void wrapClass(pybind11::class_<ReleasableImageSRGB> pyClass)
{
pyClass.def_buffer(imageSRGBDataBuffer)
.def("save", &ReleasableImageSRGB::save, py::arg("file_name"))
.def("width", &ReleasableImageSRGB::width)
.def("height", &ReleasableImageSRGB::height);
.def("height", &ReleasableImageSRGB::height)
.def(py::init<const std::string &>(), "Load image from file");
}
} // namespace ZividPython
17 changes: 17 additions & 0 deletions test/test_image_2d_bgra.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from pathlib import Path
import tempfile
import numpy
import pytest
import zivid


def test_copy_data(image_2d_bgra):
Expand Down Expand Up @@ -48,3 +52,16 @@ def test_width(image_2d_bgra):

assert width is not None
assert isinstance(width, int)


def test_load(frame_2d: zivid.Frame2D):
with frame_2d.image_bgra() as image_2d:
with tempfile.TemporaryDirectory() as tmpdir:
image_file = Path(tmpdir) / "saved_image.png"
image_2d.save(image_file)

loaded_image = zivid.Image.load(image_file, "bgra")
numpy.testing.assert_array_equal(image_2d.copy_data(), loaded_image.copy_data())

with pytest.raises(ValueError):
zivid.Image.load(image_file, "bgr")
17 changes: 17 additions & 0 deletions test/test_image_2d_rgba.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from pathlib import Path
import tempfile
import numpy
import pytest
import zivid


def test_copy_data(image_2d_rgba):
Expand Down Expand Up @@ -48,3 +52,16 @@ def test_width(image_2d_rgba):

assert width is not None
assert isinstance(width, int)


def test_load(frame_2d: zivid.Frame2D):
with frame_2d.image_rgba() as image_2d:
with tempfile.TemporaryDirectory() as tmpdir:
image_file = Path(tmpdir) / "saved_image.png"
image_2d.save(image_file)

loaded_image = zivid.Image.load(image_file, "rgba")
numpy.testing.assert_array_equal(image_2d.copy_data(), loaded_image.copy_data())

with pytest.raises(ValueError):
zivid.Image.load(image_file, "rgb")
18 changes: 17 additions & 1 deletion test/test_image_2d_srgb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from pathlib import Path
import tempfile
import numpy
import pytest

import zivid

def test_copy_data(image_2d_srgb):
import numpy as np
Expand Down Expand Up @@ -48,3 +51,16 @@ def test_width(image_2d_srgb):

assert width is not None
assert isinstance(width, int)


def test_load(frame_2d: zivid.Frame2D):
with frame_2d.image_srgb() as image_2d:
with tempfile.TemporaryDirectory() as tmpdir:
image_file = Path(tmpdir) / "saved_image.png"
image_2d.save(image_file)

loaded_image = zivid.Image.load(image_file, "srgb")
numpy.testing.assert_array_equal(image_2d.copy_data(), loaded_image.copy_data())

with pytest.raises(ValueError):
zivid.Image.load(image_file, "srg")

0 comments on commit 6c983b6

Please sign in to comment.