summaryrefslogtreecommitdiff
path: root/utils/raspberrypi/ctt/ctt_ransac.py
blob: 11515a4fab089767bffefd6e91ac2ea7c0152673 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (C) 2019, Raspberry Pi (Trading) Limited
#
# ctt_ransac.py - camera tuning tool RANSAC selector for Macbeth chart locator

import numpy as np

scale = 2


"""
constructs normalised macbeth chart corners for ransac algorithm
"""
def get_square_verts(c_err=0.05, scale=scale):
    """
    define macbeth chart corners
    """
    b_bord_x, b_bord_y = scale*8.5, scale*13
    s_bord = 6*scale
    side = 41*scale
    x_max = side*6 + 5*s_bord + 2*b_bord_x
    y_max = side*4 + 3*s_bord + 2*b_bord_y
    c1 = (0, 0)
    c2 = (0, y_max)
    c3 = (x_max, y_max)
    c4 = (x_max, 0)
    mac_norm = np.array((c1, c2, c3, c4), np.float32)
    mac_norm = np.array([mac_norm])

    square_verts = []
    square_0 = np.array(((0, 0), (0, side),
                         (side, side), (side, 0)), np.float32)
    offset_0 = np.array((b_bord_x, b_bord_y), np.float32)
    c_off = side * c_err
    offset_cont = np.array(((c_off, c_off), (c_off, -c_off),
                            (-c_off, -c_off), (-c_off, c_off)), np.float32)
    square_0 += offset_0
    square_0 += offset_cont
    """
    define macbeth square corners
    """
    for i in range(6):
        shift_i = np.array(((i*side, 0), (i*side, 0),
                            (i*side, 0), (i*side, 0)), np.float32)
        shift_bord = np.array(((i*s_bord, 0), (i*s_bord, 0),
                               (i*s_bord, 0), (i*s_bord, 0)), np.float32)
        square_i = square_0 + shift_i + shift_bord
        for j in range(4):
            shift_j = np.array(((0, j*side), (0, j*side),
                                (0, j*side), (0, j*side)), np.float32)
            shift_bord = np.array(((0, j*s_bord),
                                   (0, j*s_bord), (0, j*s_bord),
                                   (0, j*s_bord)), np.float32)
            square_j = square_i + shift_j + shift_bord
            square_verts.append(square_j)
    # print('square_verts')
    # print(square_verts)
    return np.array(square_verts, np.float32), mac_norm


def get_square_centres(c_err=0.05, scale=scale):
    """
    define macbeth square centres
    """
    verts, mac_norm = get_square_verts(c_err, scale=scale)

    centres = np.mean(verts, axis=1)
    # print('centres')
    # print(centres)
    return np.array(centres, np.float32)
/a> 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * geometry.cpp - Geometry classes tests
 */

#include <iostream>

#include <libcamera/geometry.h>

#include "test.h"

using namespace std;
using namespace libcamera;

class GeometryTest : public Test
{
protected:
	template<typename T>
	bool compare(const T &lhs, const T &rhs,
		     bool (*op)(const T &lhs, const T &rhs),
		     const char *opName, bool expect)
	{
		bool result = op(lhs, rhs);

		if (result != expect) {
			cout << lhs.toString()
			     << opName << " "
			     << rhs.toString()
			     << "test failed" << std::endl;
			return false;
		}

		return true;
	}

	int run()
	{
		/*
		 * Point tests
		 */

		/* Equality */
		if (!compare(Point(50, 100), Point(50, 100), &operator==, "==", true))
			return TestFail;

		if (!compare(Point(-50, 100), Point(-50, 100), &operator==, "==", true))
			return TestFail;

		if (!compare(Point(50, -100), Point(50, -100), &operator==, "==", true))
			return TestFail;

		if (!compare(Point(-50, -100), Point(-50, -100), &operator==, "==", true))
			return TestFail;

		/* Inequality */
		if (!compare(Point(50, 100), Point(50, 100), &operator!=, "!=", false))
			return TestFail;

		if (!compare(Point(-50, 100), Point(-50, 100), &operator!=, "!=", false))
			return TestFail;

		if (!compare(Point(50, -100), Point(50, -100), &operator!=, "!=", false))
			return TestFail;

		if (!compare(Point(-50, -100), Point(-50, -100), &operator!=, "!=", false))
			return TestFail;

		if (!compare(Point(-50, 100), Point(50, 100), &operator!=, "!=", true))
			return TestFail;

		if (!compare(Point(50, -100), Point(50, 100), &operator!=, "!=", true))
			return TestFail;

		if (!compare(Point(-50, -100), Point(50, 100), &operator!=, "!=", true))
			return TestFail;

		/* Negation */
		if (Point(50, 100) != -Point(-50, -100) ||
		    Point(50, 100) == -Point(50, -100) ||
		    Point(50, 100) == -Point(-50, 100)) {
			cout << "Point negation test failed" << endl;
			return TestFail;
		}

		/* Default constructor */
		if (Point() != Point(0, 0)) {
			cout << "Default constructor test failed" << endl;
			return TestFail;
		}

		/*
		 * Size tests
		 */

		if (!Size().isNull() || !Size(0, 0).isNull()) {
			cout << "Null size incorrectly reported as not null" << endl;
			return TestFail;
		}

		if (Size(0, 100).isNull() || Size(100, 0).isNull() || Size(100, 100).isNull()) {
			cout << "Non-null size incorrectly reported as null" << endl;
			return TestFail;
		}

		/* Test alignDownTo(), alignUpTo(), boundTo() and expandTo() */
		Size s(50, 50);

		s.alignDownTo(16, 16);
		if (s != Size(48, 48)) {
			cout << "Size::alignDownTo() test failed" << endl;
			return TestFail;
		}

		s.alignUpTo(32, 32);
		if (s != Size(64, 64)) {
			cout << "Size::alignUpTo() test failed" << endl;
			return TestFail;
		}

		s.boundTo({ 40, 40 });
		if (s != Size(40, 40)) {
			cout << "Size::boundTo() test failed" << endl;
			return TestFail;
		}

		s.expandTo({ 50, 50 });
		if (s != Size(50, 50)) {
			cout << "Size::expandTo() test failed" << endl;
			return TestFail;
		}

		s.alignDownTo(16, 16).alignUpTo(32, 32)
		 .boundTo({ 40, 80 }).expandTo({ 16, 80 });
		if (s != Size(40, 80)) {
			cout << "Size chained in-place modifiers test failed" << endl;
			return TestFail;
		}

		/* Test alignedDownTo(), alignedUpTo(), boundedTo() and expandedTo() */
		if (Size(0, 0).alignedDownTo(16, 8) != Size(0, 0) ||
		    Size(1, 1).alignedDownTo(16, 8) != Size(0, 0) ||
		    Size(16, 8).alignedDownTo(16, 8) != Size(16, 8)) {
			cout << "Size::alignedDownTo() test failed" << endl;
			return TestFail;
		}

		if (Size(0, 0).alignedUpTo(16, 8) != Size(0, 0) ||
		    Size(1, 1).alignedUpTo(16, 8) != Size(16, 8) ||
		    Size(16, 8).alignedUpTo(16, 8) != Size(16, 8)) {
			cout << "Size::alignedUpTo() test failed" << endl;
			return TestFail;
		}

		if (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) ||
		    Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) ||
		    Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) {
			cout << "Size::boundedTo() test failed" << endl;
			return TestFail;
		}

		if (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) ||
		    Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) ||
		    Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) {
			cout << "Size::expandedTo() test failed" << endl;
			return TestFail;
		}

		/* Aspect ratio tests */
		if (Size(0, 0).boundedToAspectRatio(Size(4, 3)) != Size(0, 0) ||
		    Size(1920, 1440).boundedToAspectRatio(Size(16, 9)) != Size(1920, 1080) ||
		    Size(1920, 1440).boundedToAspectRatio(Size(65536, 36864)) != Size(1920, 1080) ||
		    Size(1440, 1920).boundedToAspectRatio(Size(9, 16)) != Size(1080, 1920) ||
		    Size(1920, 1080).boundedToAspectRatio(Size(4, 3)) != Size(1440, 1080) ||
		    Size(1920, 1080).boundedToAspectRatio(Size(65536, 49152)) != Size(1440, 1080) ||
		    Size(1024, 1024).boundedToAspectRatio(Size(1, 1)) != Size(1024, 1024) ||
		    Size(1920, 1080).boundedToAspectRatio(Size(16, 9)) != Size(1920, 1080) ||
		    Size(200, 100).boundedToAspectRatio(Size(16, 9)) != Size(177, 100) ||
		    Size(300, 200).boundedToAspectRatio(Size(16, 9)) != Size(300, 168)) {
			cout << "Size::boundedToAspectRatio() test failed" << endl;
			return TestFail;
		}

		if (Size(0, 0).expandedToAspectRatio(Size(4, 3)) != Size(0, 0) ||
		    Size(1920, 1440).expandedToAspectRatio(Size(16, 9)) != Size(2560, 1440) ||
		    Size(1920, 1440).expandedToAspectRatio(Size(65536, 36864)) != Size(2560, 1440) ||
		    Size(1440, 1920).expandedToAspectRatio(Size(9, 16)) != Size(1440, 2560) ||
		    Size(1920, 1080).expandedToAspectRatio(Size(4, 3)) != Size(1920, 1440) ||
		    Size(1920, 1080).expandedToAspectRatio(Size(65536, 49152)) != Size(1920, 1440) ||
		    Size(1024, 1024).expandedToAspectRatio(Size(1, 1)) != Size(1024, 1024) ||
		    Size(1920, 1080).expandedToAspectRatio(Size(16, 9)) != Size(1920, 1080) ||
		    Size(200, 100).expandedToAspectRatio(Size(16, 9)) != Size(200, 112) ||
		    Size(300, 200).expandedToAspectRatio(Size(16, 9)) != Size(355, 200)) {
			cout << "Size::expandedToAspectRatio() test failed" << endl;
			return TestFail;
		}

		/* Size::centeredTo() tests */
		if (Size(0, 0).centeredTo(Point(50, 100)) != Rectangle(50, 100, 0, 0) ||
		    Size(0, 0).centeredTo(Point(-50, -100)) != Rectangle(-50, -100, 0, 0) ||
		    Size(100, 200).centeredTo(Point(50, 100)) != Rectangle(0, 0, 100, 200) ||
		    Size(100, 200).centeredTo(Point(-50, -100)) != Rectangle(-100, -200, 100, 200) ||
		    Size(101, 201).centeredTo(Point(-50, -100)) != Rectangle(-100, -200, 101, 201) ||
		    Size(101, 201).centeredTo(Point(-51, -101)) != Rectangle(-101, -201, 101, 201)) {
			cout << "Size::centeredTo() test failed" << endl;
			return TestFail;
		}

		/* Scale a size by a float */
		if (Size(1000, 2000) * 2.0 != Size(2000, 4000) ||
		    Size(300, 100) * 0.5 != Size(150, 50) ||
		    Size(1, 2) * 1.6 != Size(1, 3)) {
			cout << "Size::operator*() failed" << endl;
			return TestFail;
		}

		if (Size(1000, 2000) / 2.0 != Size(500, 1000) ||
		    Size(300, 100) / 0.5 != Size(600, 200) ||
		    Size(1000, 2000) / 3.0 != Size(333, 666)) {
			cout << "Size::operator*() failed" << endl;
			return TestFail;
		}

		s = Size(300, 100);
		s *= 0.3333;
		if (s != Size(99, 33)) {
			cout << "Size::operator*() test failed" << endl;
			return TestFail;
		}

		s = Size(300, 100);
		s /= 3;
		if (s != Size(100, 33)) {
			cout << "Size::operator*() test failed" << endl;
			return TestFail;
		}

		/* Test Size equality and inequality. */
		if (!compare(Size(100, 100), Size(100, 100), &operator==, "==", true))
			return TestFail;
		if (!compare(Size(100, 100), Size(100, 100), &operator!=, "!=", false))
			return TestFail;

		if (!compare(Size(100, 100), Size(200, 100), &operator==, "==", false))
			return TestFail;
		if (!compare(Size(100, 100), Size(200, 100), &operator!=, "!=", true))
			return TestFail;

		if (!compare(Size(100, 100), Size(100, 200), &operator==, "==", false))
			return TestFail;
		if (!compare(Size(100, 100), Size(100, 200), &operator!=, "!=", true))
			return TestFail;

		/* Test Size ordering based on combined with and height. */
		if (!compare(Size(100, 100), Size(200, 200), &operator<, "<", true))
			return TestFail;
		if (!compare(Size(100, 100), Size(200, 200), &operator<=, "<=", true))
			return TestFail;
		if (!compare(Size(100, 100), Size(200, 200), &operator>, ">", false))
			return TestFail;
		if (!compare(Size(100, 100), Size(200, 200), &operator>=, ">=", false))
			return TestFail;

		if (!compare(Size(200, 200), Size(100, 100), &operator<, "<", false))
			return TestFail;
		if (!compare(Size(200, 200), Size(100, 100), &operator<=, "<=", false))
			return TestFail;
		if (!compare(Size(200, 200), Size(100, 100), &operator>, ">", true))
			return TestFail;
		if (!compare(Size(200, 200), Size(100, 100), &operator>=, ">=", true))
			return TestFail;

		/* Test Size ordering based on area (with overlapping sizes). */
		if (!compare(Size(200, 100), Size(100, 400), &operator<, "<", true))
			return TestFail;
		if (!compare(Size(200, 100), Size(100, 400), &operator<=, "<=", true))
			return TestFail;
		if (!compare(Size(200, 100), Size(100, 400), &operator>, ">", false))
			return TestFail;
		if (!compare(Size(200, 100), Size(100, 400), &operator>=, ">=", false))
			return TestFail;

		if (!compare(Size(100, 400), Size(200, 100), &operator<, "<", false))
			return TestFail;
		if (!compare(Size(100, 400), Size(200, 100), &operator<=, "<=", false))
			return TestFail;
		if (!compare(Size(100, 400), Size(200, 100), &operator>, ">", true))
			return TestFail;
		if (!compare(Size(100, 400), Size(200, 100), &operator>=, ">=", true))
			return TestFail;

		/* Test Size ordering based on width (with identical areas). */
		if (!compare(Size(100, 200), Size(200, 100), &operator<, "<", true))
			return TestFail;
		if (!compare(Size(100, 200), Size(200, 100), &operator<=, "<=", true))
			return TestFail;
		if (!compare(Size(100, 200), Size(200, 100), &operator>, ">", false))
			return TestFail;
		if (!compare(Size(100, 200), Size(200, 100), &operator>=, ">=", false))
			return TestFail;

		if (!compare(Size(200, 100), Size(100, 200), &operator<, "<", false))
			return TestFail;
		if (!compare(Size(200, 100), Size(100, 200), &operator<=, "<=", false))
			return TestFail;
		if (!compare(Size(200, 100), Size(100, 200), &operator>, ">", true))
			return TestFail;
		if (!compare(Size(200, 100), Size(100, 200), &operator>=, ">=", true))
			return TestFail;

		/*
		 * Rectangle tests
		 */

		/* Test Rectangle::isNull(). */
		if (!Rectangle(0, 0, 0, 0).isNull() ||
		    !Rectangle(1, 1, 0, 0).isNull()) {
			cout << "Null rectangle incorrectly reported as not null" << endl;
			return TestFail;
		}

		if (Rectangle(0, 0, 0, 1).isNull() ||
		    Rectangle(0, 0, 1, 0).isNull() ||
		    Rectangle(0, 0, 1, 1).isNull()) {
			cout << "Non-null rectangle incorrectly reported as null" << endl;
			return TestFail;
		}

		/* Rectangle::size(), Rectangle::topLeft() and Rectangle::center() tests */
		if (Rectangle(-1, -2, 3, 4).size() != Size(3, 4) ||
		    Rectangle(0, 0, 100000, 200000).size() != Size(100000, 200000)) {
			cout << "Rectangle::size() test failed" << endl;
			return TestFail;
		}

		if (Rectangle(1, 2, 3, 4).topLeft() != Point(1, 2) ||
		    Rectangle(-1, -2, 3, 4).topLeft() != Point(-1, -2)) {
			cout << "Rectangle::topLeft() test failed" << endl;
			return TestFail;
		}

		if (Rectangle(0, 0, 300, 400).center() != Point(150, 200) ||
		    Rectangle(-1000, -2000, 300, 400).center() != Point(-850, -1800) ||
		    Rectangle(10, 20, 301, 401).center() != Point(160, 220) ||
		    Rectangle(11, 21, 301, 401).center() != Point(161, 221) ||
		    Rectangle(-1011, -2021, 301, 401).center() != Point(-861, -1821)) {
			cout << "Rectangle::center() test failed" << endl;
			return TestFail;
		}

		/* Rectangle::boundedTo() (intersection function) */
		if (Rectangle(0, 0, 1000, 2000).boundedTo(Rectangle(0, 0, 1000, 2000)) !=
			    Rectangle(0, 0, 1000, 2000) ||
		    Rectangle(-500, -1000, 1000, 2000).boundedTo(Rectangle(0, 0, 1000, 2000)) !=
			    Rectangle(0, 0, 500, 1000) ||
		    Rectangle(500, 1000, 1000, 2000).boundedTo(Rectangle(0, 0, 1000, 2000)) !=
			    Rectangle(500, 1000, 500, 1000) ||
		    Rectangle(300, 400, 50, 100).boundedTo(Rectangle(0, 0, 1000, 2000)) !=
			    Rectangle(300, 400, 50, 100) ||
		    Rectangle(0, 0, 1000, 2000).boundedTo(Rectangle(300, 400, 50, 100)) !=
			    Rectangle(300, 400, 50, 100) ||
		    Rectangle(0, 0, 100, 100).boundedTo(Rectangle(50, 100, 100, 100)) !=
			    Rectangle(50, 100, 50, 0) ||
		    Rectangle(0, 0, 100, 100).boundedTo(Rectangle(100, 50, 100, 100)) !=
			    Rectangle(100, 50, 0, 50) ||
		    Rectangle(-10, -20, 10, 20).boundedTo(Rectangle(10, 20, 100, 100)) !=
			    Rectangle(10, 20, 0, 0)) {
			cout << "Rectangle::boundedTo() test failed" << endl;
			return TestFail;
		}

		/* Rectangle::enclosedIn() tests */
		if (Rectangle(10, 20, 300, 400).enclosedIn(Rectangle(-10, -20, 1300, 1400)) !=
			    Rectangle(10, 20, 300, 400) ||
		    Rectangle(-100, -200, 3000, 4000).enclosedIn(Rectangle(-10, -20, 1300, 1400)) !=
			    Rectangle(-10, -20, 1300, 1400) ||
		    Rectangle(-100, -200, 300, 400).enclosedIn(Rectangle(-10, -20, 1300, 1400)) !=
			    Rectangle(-10, -20, 300, 400) ||
		    Rectangle(5100, 6200, 300, 400).enclosedIn(Rectangle(-10, -20, 1300, 1400)) !=
			    Rectangle(990, 980, 300, 400) ||
		    Rectangle(100, -300, 150, 200).enclosedIn(Rectangle(50, 0, 200, 300)) !=
			    Rectangle(100, 0, 150, 200) ||
		    Rectangle(100, -300, 150, 1200).enclosedIn(Rectangle(50, 0, 200, 300)) !=
			    Rectangle(100, 0, 150, 300) ||
		    Rectangle(-300, 100, 200, 150).enclosedIn(Rectangle(0, 50, 300, 200)) !=
			    Rectangle(0, 100, 200, 150) ||
		    Rectangle(-300, 100, 1200, 150).enclosedIn(Rectangle(0, 50, 300, 200)) !=
			    Rectangle(0, 100, 300, 150)) {
			cout << "Rectangle::enclosedIn() test failed" << endl;
			return TestFail;
		}

		/* Rectange::scaledBy() tests */
		if (Rectangle(10, 20, 300, 400).scaledBy(Size(0, 0), Size(1, 1)) !=
			    Rectangle(0, 0, 0, 0) ||
		    Rectangle(10, -20, 300, 400).scaledBy(Size(32768, 65536), Size(32768, 32768)) !=
			    Rectangle(10, -40, 300, 800) ||
		    Rectangle(-30000, 10000, 20000, 20000).scaledBy(Size(7, 7), Size(7, 7)) !=
			    Rectangle(-30000, 10000, 20000, 20000) ||
		    Rectangle(-20, -30, 320, 240).scaledBy(Size(1280, 960), Size(640, 480)) !=
			    Rectangle(-40, -60, 640, 480) ||
		    Rectangle(1, 1, 2026, 1510).scaledBy(Size(4056, 3024), Size(2028, 1512)) !=
			    Rectangle(2, 2, 4052, 3020)) {
			cout << "Rectangle::scaledBy() test failed" << endl;
			return TestFail;
		}

		/* Rectangle::translatedBy() tests */
		if (Rectangle(10, -20, 300, 400).translatedBy(Point(-30, 40)) !=
			    Rectangle(-20, 20, 300, 400) ||
		    Rectangle(-10, 20, 400, 300).translatedBy(Point(50, -60)) !=
			    Rectangle(40, -40, 400, 300)) {
			cout << "Rectangle::translatedBy() test failed" << endl;
			return TestFail;
		}

		/* Rectangle::scaleBy() tests */
		Rectangle r(-20, -30, 320, 240);
		r.scaleBy(Size(1280, 960), Size(640, 480));
		if (r != Rectangle(-40, -60, 640, 480)) {
			cout << "Rectangle::scaleBy() test failed" << endl;
			return TestFail;
		}

		r = Rectangle(1, 1, 2026, 1510);
		r.scaleBy(Size(4056, 3024), Size(2028, 1512));
		if (r != Rectangle(2, 2, 4052, 3020)) {
			cout << "Rectangle::scaleBy() test failed" << endl;
			return TestFail;
		}

		/* Rectangle::translateBy() tests */
		r = Rectangle(10, -20, 300, 400);
		r.translateBy(Point(-30, 40));
		if (r != Rectangle(-20, 20, 300, 400)) {
			cout << "Rectangle::translateBy() test failed" << endl;
			return TestFail;
		}

		r = Rectangle(-10, 20, 400, 300);
		r.translateBy(Point(50, -60));
		if (r != Rectangle(40, -40, 400, 300)) {
			cout << "Rectangle::translateBy() test failed" << endl;
			return TestFail;
		}

		return TestPass;
	}
};

TEST_REGISTER(GeometryTest)