Beispiel #1
0
 def test_case(self):
     array1 = np.random.randint(0, 255, size=(10, 10, 3), dtype=np.uint8)
     array2 = np.random.randint(0, 255, size=(10, 10, 3), dtype=np.uint8)
     img1 = Image(array1)
     img2 = Image(array2)
     op = CrossCorrelate2D()
     op.on(img1, img2)
Beispiel #2
0
    def test_concatenate_invalid_dtype(self):
        """concate works only with Image with same dtype"""
        img1 = Image(np.ones((200, 100, 3), dtype=np.uint8), dtype=np.float32)
        img2 = Image(np.ones((200, 100, 3), dtype=np.uint8), dtype=np.uint8)

        with pytest.raises(ValueError):
            concate = img1.concate(img2, axis=0)
Beispiel #3
0
 def on(self, image: Image, mask: Image):
     color_mask = mask.to_color()
     color_mask[mask.to_gray() > 0, :] = self._color
     color_mask[mask.to_gray() <= 0, :] = [0, 0, 0]
     result = cv2.addWeighted(
         src1=image.to_color(), alpha=0.9,
         src2=color_mask, beta=0.1,
         gamma=0
     )
     return Image(result)
Beispiel #4
0
    def test_from_invalid_array(self):
        """Image object should refuse invalid array"""
        wrong_dimension = np.random.randint(
            0, 255, size=(100, 500, 1), dtype=np.uint8
        )
        with pytest.raises(ValueError):
            img = Image(wrong_dimension, to_color=False)

        wrong_dtype = np.random.randint(0, 255, size=(100, 500, 3))
        wrong_dtype = wrong_dtype.astype(np.float32)
        with pytest.raises(ValueError):
            img = Image(wrong_dtype)
Beispiel #5
0
    def test_from_array(self):
        """Image object can created from uint8 numpy array"""
        array = np.random.randint(0, 255, size=(100, 500, 3), dtype=np.uint8)
        img = Image(array)
        assert img.name == "array_" + str(id(array))
        assert img.is_color
        assert _is_ref_unequal(img, array)

        array = np.random.randint(0, 255, size=(100, 500), dtype=np.uint8)
        img = Image(array)
        assert img.name == "array_" + str(id(array))
        assert not img.is_color
        assert _is_ref_unequal(img, array)
Beispiel #6
0
def display(img: Image, title: str = None):
    """Display image content via pop-up windows"""
    dst_shape = _get_keep_aspect_ratio_shape(
        target_shape=img.shape[:2], dst_shape=_get_curr_montior_geometry())

    if dst_shape != img.shape:
        img = img.resize(dst_shape)

    if title is None:
        title = img.name

    cv2.imshow(title, img.astype(np.uint8))
    cv2.waitKey()
Beispiel #7
0
    def on(self, img: Image) -> Image:
        """Operate on single image"""
        if self._color == "color":
            img = img.to_color()
        elif self._color == "gray":
            img = img.to_gray()
        elif self._color != "unchanged":
            msg = "Unrecognized color option: {}".format(self._color)
            raise ValueError(msg)

        if self._cvt_to_f32:
            img = img.astype(np.float32, copy=False)
        result_array = self._operate(img)
        name = "{} on ".format(self.__class__.__name__) + img.name
        return Image(result_array, name=name)
Beispiel #8
0
    def test_resize_invalid_interpolation(self):
        """.resize() should raise ValueError when interpolation is invalid"""
        file = str(SAMPLE_IMAGES[0])
        img = Image.from_file(file)

        with pytest.raises(ValueError):
            img.resize((224, 224), interpolation="NOT_EXIST")
Beispiel #9
0
    def test_inside_image(self):
        """Point.inside should return right result"""
        sample_img = Image(np.zeros((100, 200, 3), dtype=np.uint8))

        # test 4 corners
        top_left = Point(y=0, x=0)
        bottom_left = Point(y=99, x=0)
        top_right = Point(y=0, x=199)
        bottom_right = Point(y=99, x=199)

        assert top_left.inside(sample_img)
        assert bottom_left.inside(sample_img)
        assert top_right.inside(sample_img)
        assert bottom_right.inside(sample_img)

        # test out-side point
        pt1 = Point(y=-1, x=50)
        pt2 = Point(y=100, x=50)
        pt3 = Point(y=50, x=-1)
        pt4 = Point(y=50, x=200)

        assert not pt1.inside(sample_img)
        assert not pt2.inside(sample_img)
        assert not pt3.inside(sample_img)
        assert not pt4.inside(sample_img)
Beispiel #10
0
    def test_slice(self):
        """Slice on image should use original array, and keep name"""
        img = Image(np.random.randint(0, 255, size=(100, 500, 3), dtype=np.uint8))

        sliced = img[...]
        assert np.allclose(sliced, img)
        assert sliced.name == img.name
        assert not _is_ref_unequal(sliced, img)
Beispiel #11
0
    def test_resize_bw(self):
        """Test bw image resize, it should keep original name"""
        file = str(IMAGE_BW)
        img = Image.from_file(file)
        assert not img.is_color
        assert img.shape != (100, 400)

        resize = img.resize((100, 400))
        assert img.name == resize.name
        assert resize.shape == (100, 400)
Beispiel #12
0
    def test_simple_cases(self, array1, array2):
        """Sample cases for validate AbsDiff"""
        img1 = Image(array1)
        img2 = Image(array2)
        zero = Image(np.zeros(img2.shape, dtype=np.uint8))
        operation = AbsDiff()

        result = operation.on(img1, zero)
        assert np.all(result == array1)
        assert np.all(img1 == array1)
        assert np.all(zero == 0)

        result = operation.on(zero, img1)
        assert np.all(result == array1)
        assert np.all(img1 == array1)
        assert np.all(zero == 0)

        result1 = operation.on(img2, img1)
        result2 = operation.on(img1, img2)
        assert np.all(result1 == result2)
Beispiel #13
0
    def test_concatenate_invalid_shape(self):
        """concate works only with Image of same height/width for x/y"""
        same_w1 = Image(np.ones((10, 14, 3), dtype=np.uint8))
        same_w2 = Image(np.ones((20, 14, 3), dtype=np.uint8))
        same_h1 = Image(np.ones((20, 15, 3), dtype=np.uint8))
        same_h2 = Image(np.ones((20, 30, 3), dtype=np.uint8))

        with pytest.raises(ValueError):
            concate = same_w1.concate(same_w2, axis=1)

        with pytest.raises(ValueError):
            concate = same_h1.concate(same_h2, axis=0)

        concate = same_w1.concate(same_w2, axis=0)
        assert isinstance(concate, Image)
        assert concate.shape == (30, 14, 3)

        concate = same_h1.concate(same_h2, axis=1)
        assert isinstance(concate, Image)
        assert concate.shape == (20, 45, 3)
Beispiel #14
0
    def test_save_to_file(self, tmp_path: pathlib.Path, sample):
        file = str(sample)
        img = Image.from_file(file)

        file_name = "test_save_file.png"
        file = tmp_path.joinpath(file_name)
        img.save(str(file))

        assert file.is_file()
        cv2_read = cv2.imread(str(file), flags=cv2.IMREAD_UNCHANGED)
        assert np.allclose(cv2_read, img)

        # save to same file should return error
        file2 = str(sample)
        img = Image.from_file(file2)

        with pytest.raises(ValueError):
            img.save(str(file), overwrite=False)

        img.save(str(file), overwrite=True)
Beispiel #15
0
    def test_properties(self):
        """Image name, h, w and shape properties should match that of .numpy()"""
        file = SAMPLE_IMAGES[0]
        img = Image.from_file(str(file))
        assert img.name == file.stem

        assert img.h == 260
        assert img.w == 260
        assert len(img.shape) == 3
        assert img.ndim == 3
        assert img.c == 3
Beispiel #16
0
    def test_color_conversion(self):
        """Convert to same color space return original ref, otherwise return the converted"""
        color = Image.from_file(SAMPLE_IMAGES[0])
        assert color.is_color

        color_to_color = color.to_color()
        assert color_to_color.is_color
        assert id(color_to_color) == id(color)

        color_to_gray = color.to_gray()
        assert not color_to_gray.is_color
        assert id(color_to_gray) != id(color)

        gray = Image.from_file(IMAGE_BW)
        gray_to_color = gray.to_color()
        assert gray_to_color.is_color
        assert id(gray_to_color) != id(gray)

        gray_to_gray = gray.to_gray()
        assert not gray_to_gray.is_color
        assert id(gray_to_gray) == id(gray)
Beispiel #17
0
    def test_resize_invalid_shape(self):
        """.resize() should raise ValueError when shape is invalid"""
        file = str(SAMPLE_IMAGES[0])
        img = Image.from_file(file)

        with pytest.raises(ValueError):
            img.resize((224, ))

        with pytest.raises(ValueError):
            img.resize((224, -1))

        with pytest.raises(ValueError):
            img.resize((113.6, 3.1415))
Beispiel #18
0
    def test_math_operators_with_images(self, operand):
        """Test image basic math operation with another image"""
        operator = _Operands[operand]

        array1 = np.arange(1, 251).reshape(10, 25).astype(np.uint8)
        array2 = np.arange(250, 0, -1).reshape(10, 25).astype(np.uint8)

        image1 = Image(array1)
        image2 = Image(array2)

        op = operator(image1, image2)
        r_op = operator(image2, image1)

        result = operator(array1, array2)
        r_result = operator(array2, array1)

        assert np.all(op == result)
        assert np.all(r_op == r_result)

        # commutative operator
        if operand in ["+", "*"]:
            assert np.all(op == r_op)
Beispiel #19
0
    def test_resize_color(self):
        """Test color image resize, it should keep original name"""
        file = str(SAMPLE_IMAGES[0])
        img = Image.from_file(file)
        assert img.is_color

        resize = img.resize((100, 400))
        assert img.name == resize.name
        assert resize.shape == (100, 400, 3)

        resize = img.resize((100, 400), interpolation="INTER_LINEAR")
        assert img.name == resize.name
        assert resize.shape == (100, 400, 3)

        resize = img.resize((400, 200), interpolation="INTER_CUBIC")
        assert img.name == resize.name
        assert resize.shape == (400, 200, 3)
Beispiel #20
0
    def test_math_operators_with_constant(self, operand):
        """Test image basic math operation on constants"""
        operator = _Operands[operand]
        array = np.arange(1, 251).reshape(50, 5).astype(np.uint8)
        constant = 10

        image = Image(array)
        op = operator(image, constant)
        r_op = operator(constant, image)

        result = operator(array, constant)
        r_result = operator(constant, array)
        assert np.all(op == result)
        assert np.all(r_op == r_result)

        # commutative operator
        if operand in ["+", "*"]:
            assert np.all(op == r_op)
Beispiel #21
0
    def on(self, img1: Image, img2: Image) -> Image:
        """Operate on two images"""
        if self._color == "color":
            img1 = img1.to_color()
            img2 = img2.to_color()
        elif self._color == "gray":
            img1 = img1.to_gray()
            img2 = img2.to_gray()
        elif self._color != "unchanged":
            msg = "Unrecognized color option: {}".format(self._color)
            raise ValueError(msg)

        if self._cvt_to_f32:
            img1 = img1.astype(np.float32, copy=False)
            img2 = img2.astype(np.float32, copy=False)

        result_array = self._operate(img1, img2)
        name = "{} on ({}, {})".format(
            self.__class__.__name__, img1.name, img2.name
        )
        return Image(result_array, name=name)
Beispiel #22
0
 def test_canny(self, file):
     """Canny should work on both color and gray image"""
     img = Image.from_file(file)
     op = Canny()
     canny = op.on(img)
     assert not canny.is_color
Beispiel #23
0
 def test_laplacian(self, file):
     """Laplacian should work on both color and gray image"""
     img = Image.from_file(file)
     op = Laplacian()
     laplace = op.on(img)
     assert laplace.is_color == img.is_color
Beispiel #24
0
 def test_recreate(self, img):
     """Recreate Image from given Image should use copy of original array"""
     recreate = Image(img)
     assert np.allclose(recreate, img)
     assert _is_ref_unequal(recreate, img)
Beispiel #25
0
 def test_from_invalid_file(self, sample):
     """Create Image object from invalid files should raise ValueError"""
     with pytest.raises(ValueError):
         img = Image.from_file(sample)
Beispiel #26
0
 def test_from_invalid_file_uncaught(self, sample):
     """There images are broken, but Image object won't detect"""
     with pytest.raises(ValueError):
         img = Image.from_file(sample)
Beispiel #27
0
 def test_from_file_blackwhite(self):
     """Image object can and should be loaded from black white image"""
     img = Image.from_file(IMAGE_BW)
     assert img.name == IMAGE_BW.stem
     assert not img.is_color
Beispiel #28
0
 def test_from_file_color(self):
     """Image object can and should be loaded from color image file"""
     for file in SAMPLE_IMAGES:
         img = Image.from_file(str(file))
         assert img.name == file.stem
         assert img.is_color
Beispiel #29
0
class TestImageObject:

    def test_from_file_color(self):
        """Image object can and should be loaded from color image file"""
        for file in SAMPLE_IMAGES:
            img = Image.from_file(str(file))
            assert img.name == file.stem
            assert img.is_color

    def test_from_file_blackwhite(self):
        """Image object can and should be loaded from black white image"""
        img = Image.from_file(IMAGE_BW)
        assert img.name == IMAGE_BW.stem
        assert not img.is_color

    def test_from_array(self):
        """Image object can created from uint8 numpy array"""
        array = np.random.randint(0, 255, size=(100, 500, 3), dtype=np.uint8)
        img = Image(array)
        assert img.name == "array_" + str(id(array))
        assert img.is_color
        assert _is_ref_unequal(img, array)

        array = np.random.randint(0, 255, size=(100, 500), dtype=np.uint8)
        img = Image(array)
        assert img.name == "array_" + str(id(array))
        assert not img.is_color
        assert _is_ref_unequal(img, array)

    def test_from_invalid_array(self):
        """Image object should refuse invalid array"""
        wrong_dimension = np.random.randint(
            0, 255, size=(100, 500, 1), dtype=np.uint8
        )
        with pytest.raises(ValueError):
            img = Image(wrong_dimension, to_color=False)

        wrong_dtype = np.random.randint(0, 255, size=(100, 500, 3))
        wrong_dtype = wrong_dtype.astype(np.float32)
        with pytest.raises(ValueError):
            img = Image(wrong_dtype)

    @pytest.mark.parametrize(
        "img", [
            Image(np.random.randint(0, 255, size=(100, 500, 3), dtype=np.uint8)),
            Image(np.random.randint(0, 255, size=(100, 500), dtype=np.uint8))
        ],
        ids=["color", "bw"]
    )
    def test_change_type(self, img):
        """.astype(dtype) should use copy of original array, and keep name"""
        assert img.dtype == np.uint8

        change_type = img.astype(np.float32)
        assert np.allclose(change_type, img)
        assert change_type.name == img.name
        assert _is_ref_unequal(change_type, img)

        # check the reference of the numpy
        unchange_type = img.astype(np.uint8)
        assert np.allclose(unchange_type, img)
        assert unchange_type.name == img.name
        assert _is_ref_unequal(unchange_type, img)

    def test_slice(self):
        """Slice on image should use original array, and keep name"""
        img = Image(np.random.randint(0, 255, size=(100, 500, 3), dtype=np.uint8))

        sliced = img[...]
        assert np.allclose(sliced, img)
        assert sliced.name == img.name
        assert not _is_ref_unequal(sliced, img)

    @pytest.mark.parametrize(
        "img", [
            Image(np.random.randint(0, 255, size=(100, 500, 3), dtype=np.uint8)),
            Image(np.random.randint(0, 255, size=(100, 500), dtype=np.uint8))
        ],
        ids=["color", "bw"]
    )
    def test_recreate(self, img):
        """Recreate Image from given Image should use copy of original array"""
        recreate = Image(img)
        assert np.allclose(recreate, img)
        assert _is_ref_unequal(recreate, img)

    def test_properties(self):
        """Image name, h, w and shape properties should match that of .numpy()"""
        file = SAMPLE_IMAGES[0]
        img = Image.from_file(str(file))
        assert img.name == file.stem

        assert img.h == 260
        assert img.w == 260
        assert len(img.shape) == 3
        assert img.ndim == 3
        assert img.c == 3

    def test_color_conversion(self):
        """Convert to same color space return original ref, otherwise return the converted"""
        color = Image.from_file(SAMPLE_IMAGES[0])
        assert color.is_color

        color_to_color = color.to_color()
        assert color_to_color.is_color
        assert id(color_to_color) == id(color)

        color_to_gray = color.to_gray()
        assert not color_to_gray.is_color
        assert id(color_to_gray) != id(color)

        gray = Image.from_file(IMAGE_BW)
        gray_to_color = gray.to_color()
        assert gray_to_color.is_color
        assert id(gray_to_color) != id(gray)

        gray_to_gray = gray.to_gray()
        assert not gray_to_gray.is_color
        assert id(gray_to_gray) == id(gray)

    @pytest.mark.parametrize(
        "sample", [str(file) for file in INVALID_IMAGES]
    )
    def test_from_invalid_file(self, sample):
        """Create Image object from invalid files should raise ValueError"""
        with pytest.raises(ValueError):
            img = Image.from_file(sample)

    @pytest.mark.parametrize(
        "sample", [SAMPLE_IMAGES[0], IMAGE_BW], ids=["color", "bw"]
    )
    def test_save_to_file(self, tmp_path: pathlib.Path, sample):
        file = str(sample)
        img = Image.from_file(file)

        file_name = "test_save_file.png"
        file = tmp_path.joinpath(file_name)
        img.save(str(file))

        assert file.is_file()
        cv2_read = cv2.imread(str(file), flags=cv2.IMREAD_UNCHANGED)
        assert np.allclose(cv2_read, img)

        # save to same file should return error
        file2 = str(sample)
        img = Image.from_file(file2)

        with pytest.raises(ValueError):
            img.save(str(file), overwrite=False)

        img.save(str(file), overwrite=True)

    @pytest.mark.xfail(reason="Image object can not detect these image defects")
    @pytest.mark.parametrize(
        "sample", [str(file) for file in UNDETECTED_IMAGES]
    )
    def test_from_invalid_file_uncaught(self, sample):
        """There images are broken, but Image object won't detect"""
        with pytest.raises(ValueError):
            img = Image.from_file(sample)

    def test_resize_color(self):
        """Test color image resize, it should keep original name"""
        file = str(SAMPLE_IMAGES[0])
        img = Image.from_file(file)
        assert img.is_color

        resize = img.resize((100, 400))
        assert img.name == resize.name
        assert resize.shape == (100, 400, 3)

        resize = img.resize((100, 400), interpolation="INTER_LINEAR")
        assert img.name == resize.name
        assert resize.shape == (100, 400, 3)

        resize = img.resize((400, 200), interpolation="INTER_CUBIC")
        assert img.name == resize.name
        assert resize.shape == (400, 200, 3)

    def test_resize_bw(self):
        """Test bw image resize, it should keep original name"""
        file = str(IMAGE_BW)
        img = Image.from_file(file)
        assert not img.is_color
        assert img.shape != (100, 400)

        resize = img.resize((100, 400))
        assert img.name == resize.name
        assert resize.shape == (100, 400)

    def test_resize_invalid_shape(self):
        """.resize() should raise ValueError when shape is invalid"""
        file = str(SAMPLE_IMAGES[0])
        img = Image.from_file(file)

        with pytest.raises(ValueError):
            img.resize((224, ))

        with pytest.raises(ValueError):
            img.resize((224, -1))

        with pytest.raises(ValueError):
            img.resize((113.6, 3.1415))

    def test_resize_invalid_interpolation(self):
        """.resize() should raise ValueError when interpolation is invalid"""
        file = str(SAMPLE_IMAGES[0])
        img = Image.from_file(file)

        with pytest.raises(ValueError):
            img.resize((224, 224), interpolation="NOT_EXIST")

    def test_concatenate_invalid_dtype(self):
        """concate works only with Image with same dtype"""
        img1 = Image(np.ones((200, 100, 3), dtype=np.uint8), dtype=np.float32)
        img2 = Image(np.ones((200, 100, 3), dtype=np.uint8), dtype=np.uint8)

        with pytest.raises(ValueError):
            concate = img1.concate(img2, axis=0)

    def test_concatenate_invalid_shape(self):
        """concate works only with Image of same height/width for x/y"""
        same_w1 = Image(np.ones((10, 14, 3), dtype=np.uint8))
        same_w2 = Image(np.ones((20, 14, 3), dtype=np.uint8))
        same_h1 = Image(np.ones((20, 15, 3), dtype=np.uint8))
        same_h2 = Image(np.ones((20, 30, 3), dtype=np.uint8))

        with pytest.raises(ValueError):
            concate = same_w1.concate(same_w2, axis=1)

        with pytest.raises(ValueError):
            concate = same_h1.concate(same_h2, axis=0)

        concate = same_w1.concate(same_w2, axis=0)
        assert isinstance(concate, Image)
        assert concate.shape == (30, 14, 3)

        concate = same_h1.concate(same_h2, axis=1)
        assert isinstance(concate, Image)
        assert concate.shape == (20, 45, 3)