summaryrefslogtreecommitdiff
path: root/utils/raspberrypi/ctt/ctt_ransac.py
blob: 9ed7d93c511fc9ff4be4f39163e8d426c95a15a4 (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 Ltd
#
# 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)
pan>enumerator_->enumerate()) { cerr << "Failed to enumerate media devices" << endl; return TestFail; } DeviceMatch dm("vim2m"); dm.add("vim2m-source"); dm.add("vim2m-sink"); media_ = enumerator_->search(dm); if (!media_) { cerr << "No vim2m device found" << endl; return TestSkip; } return TestPass; } int run() { constexpr unsigned int bufferCount = 4; EventDispatcher *dispatcher = Thread::current()->eventDispatcher(); int ret; MediaEntity *entity = media_->getEntityByName("vim2m-source"); vim2m_ = new V4L2M2MDevice(entity->deviceNode()); if (vim2m_->open()) { cerr << "Failed to open VIM2M device" << endl; return TestFail; } V4L2VideoDevice *capture = vim2m_->capture(); V4L2VideoDevice *output = vim2m_->output(); V4L2DeviceFormat format = {}; if (capture->getFormat(&format)) { cerr << "Failed to get capture format" << endl; return TestFail; } format.size.width = 640; format.size.height = 480; if (capture->setFormat(&format)) { cerr << "Failed to set capture format" << endl; return TestFail; } if (output->setFormat(&format)) { cerr << "Failed to set output format" << endl; return TestFail; } ret = capture->allocateBuffers(bufferCount, &captureBuffers_); if (ret < 0) { cerr << "Failed to allocate Capture Buffers" << endl; return TestFail; } ret = output->allocateBuffers(bufferCount, &outputBuffers_); if (ret < 0) { cerr << "Failed to allocate Output Buffers" << endl; return TestFail; } capture->bufferReady.connect(this, &V4L2M2MDeviceTest::receiveCaptureBuffer); output->bufferReady.connect(this, &V4L2M2MDeviceTest::outputBufferComplete); for (const std::unique_ptr<FrameBuffer> &buffer : captureBuffers_) { if (capture->queueBuffer(buffer.get())) { std::cout << "Failed to queue capture buffer" << std::endl; return TestFail; } } for (const std::unique_ptr<FrameBuffer> &buffer : outputBuffers_) { if (output->queueBuffer(buffer.get())) { std::cout << "Failed to queue output buffer" << std::endl; return TestFail; } } ret = capture->streamOn(); if (ret) { cerr << "Failed to streamOn capture" << endl; return TestFail; } ret = output->streamOn(); if (ret) { cerr << "Failed to streamOn output" << endl; return TestFail; } Timer timeout; timeout.start(5000); while (timeout.isRunning()) { dispatcher->processEvents(); if (captureFrames_ > 30) break; } cerr << "Output " << outputFrames_ << " frames" << std::endl; cerr << "Captured " << captureFrames_ << " frames" << std::endl; if (captureFrames_ < 30) { cerr << "Failed to capture 30 frames within timeout." << std::endl; return TestFail; } ret = capture->streamOff(); if (ret) { cerr << "Failed to StreamOff the capture device." << std::endl; return TestFail; } ret = output->streamOff(); if (ret) { cerr << "Failed to StreamOff the output device." << std::endl; return TestFail; } return TestPass; } void cleanup() { delete vim2m_; }; private: std::unique_ptr<DeviceEnumerator> enumerator_; std::shared_ptr<MediaDevice> media_; V4L2M2MDevice *vim2m_; std::vector<std::unique_ptr<FrameBuffer>> captureBuffers_; std::vector<std::unique_ptr<FrameBuffer>> outputBuffers_; unsigned int outputFrames_; unsigned int captureFrames_; }; TEST_REGISTER(V4L2M2MDeviceTest);