128 lines
5.1 KiB
Python
128 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
# This file is part of OpenCV project.
|
|
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
|
# of this distribution and at http://opencv.org/license.html.
|
|
|
|
import numpy as np
|
|
import cv2 as cv
|
|
from tests_common import NewOpenCVTests
|
|
|
|
EXPECTED_COEFFS_SIZE = 78
|
|
|
|
class ChromaticAberrationTest(NewOpenCVTests):
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.test_yaml_file = self.find_file(
|
|
"cv/cameracalibration/chromatic_aberration/ca_photo_calib.yaml"
|
|
)
|
|
|
|
self.test_image = self.get_sample(
|
|
"cv/cameracalibration/chromatic_aberration/ca_photo.png", 1
|
|
)
|
|
self.assertIsNotNone(self.test_image, "Failed to load test image")
|
|
self.assertFalse(self.test_image.size == 0, "Failed to load test image")
|
|
|
|
def test_load_calib_and_correct_image(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
coeffMat, calib_size, degree = cv.loadChromaticAberrationParams(fs.root())
|
|
|
|
self.assertIsInstance(coeffMat, np.ndarray)
|
|
self.assertEqual(coeffMat.dtype, np.float32)
|
|
self.assertEqual(coeffMat.shape[0], 4)
|
|
self.assertGreater(coeffMat.shape[1], 0)
|
|
self.assertGreater(degree, 0)
|
|
self.assertGreater(calib_size[0], 0)
|
|
self.assertGreater(calib_size[1], 0)
|
|
self.assertEqual(coeffMat.shape[1], EXPECTED_COEFFS_SIZE)
|
|
|
|
self.assertEqual(self.test_image.shape[1], calib_size[0])
|
|
self.assertEqual(self.test_image.shape[0], calib_size[1])
|
|
|
|
corrected = cv.correctChromaticAberration(self.test_image, coeffMat, calib_size, degree)
|
|
|
|
self.assertEqual(corrected.shape[:2], self.test_image.shape[:2])
|
|
self.assertEqual(corrected.dtype, self.test_image.dtype)
|
|
|
|
diff = cv.absdiff(self.test_image, corrected)
|
|
sum_diff = cv.sumElems(diff)
|
|
self.assertGreater(sum(sum_diff[:3]), 0.0)
|
|
|
|
def test_yaml_contents_as_expected(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
|
|
red_node = fs.getNode("red_channel")
|
|
blue_node = fs.getNode("blue_channel")
|
|
self.assertTrue(red_node.isMap())
|
|
self.assertTrue(blue_node.isMap())
|
|
|
|
coeffs_x = red_node.getNode("coeffs_x")
|
|
self.assertIsNotNone(coeffs_x)
|
|
self.assertEqual(coeffs_x.size(), EXPECTED_COEFFS_SIZE)
|
|
|
|
coeffs_x = blue_node.getNode("coeffs_x")
|
|
self.assertIsNotNone(coeffs_x)
|
|
self.assertEqual(coeffs_x.size(), EXPECTED_COEFFS_SIZE)
|
|
|
|
coeffs_y = red_node.getNode("coeffs_y")
|
|
self.assertIsNotNone(coeffs_y)
|
|
self.assertEqual(coeffs_y.size(), EXPECTED_COEFFS_SIZE)
|
|
|
|
coeffs_y = blue_node.getNode("coeffs_y")
|
|
self.assertIsNotNone(coeffs_y)
|
|
self.assertEqual(coeffs_y.size(), EXPECTED_COEFFS_SIZE)
|
|
|
|
fs.release()
|
|
|
|
def test_invalid_single_channel(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
coeffMat, calib_size, degree = cv.loadChromaticAberrationParams(fs.root())
|
|
|
|
|
|
gray = cv.cvtColor(self.test_image, cv.COLOR_BGR2GRAY)
|
|
with self.assertRaises(cv.error):
|
|
_ = cv.correctChromaticAberration(gray, coeffMat, calib_size, degree)
|
|
|
|
def test_empty_coeff_mat(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
_, calib_size, degree = cv.loadChromaticAberrationParams(fs.root())
|
|
|
|
emptyCoeff = np.empty((0, 0), dtype=np.float32)
|
|
with self.assertRaises(cv.error):
|
|
_ = cv.correctChromaticAberration(self.test_image, emptyCoeff, calib_size, degree)
|
|
|
|
def test_mismatched_image_size(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
coeffMat, calib_size, degree = cv.loadChromaticAberrationParams(fs.root())
|
|
|
|
resized = cv.resize(self.test_image, (self.test_image.shape[1] // 2, self.test_image.shape[0] // 2))
|
|
with self.assertRaises(cv.error):
|
|
_ = cv.correctChromaticAberration(resized, coeffMat, calib_size, degree)
|
|
|
|
def test_wrong_coeff_type(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
coeffMat, calib_size, degree = cv.loadChromaticAberrationParams(fs.root())
|
|
|
|
wrongType = coeffMat.astype(np.float64)
|
|
with self.assertRaises(cv.error):
|
|
_ = cv.correctChromaticAberration(self.test_image, wrongType, calib_size, degree)
|
|
|
|
def test_degree_does_not_match_coeff_cols(self):
|
|
fs = cv.FileStorage(self.test_yaml_file, cv.FileStorage_READ)
|
|
self.assertTrue(fs.isOpened())
|
|
coeffMat, calib_size, degree = cv.loadChromaticAberrationParams(fs.root())
|
|
|
|
wrongDegree = max(1, degree - 1)
|
|
self.assertNotEqual(wrongDegree, coeffMat.shape[1])
|
|
with self.assertRaises(cv.error):
|
|
_ = cv.correctChromaticAberration(self.test_image, coeffMat, calib_size, wrongDegree)
|
|
|
|
if __name__ == '__main__':
|
|
NewOpenCVTests.bootstrap()
|