извлечение четырехстороннего изображения к прямоугольнику

A photo

ОБНОВЛЕНИЕ ЩЕДРОСТИ

Переходя по ссылке Denis, это - то, как использовать threeblindmiceandamonkey код:

// the destination rect is our 'in' quad
int dw = 300, dh = 250;
double in[4][4] = {{0,0},{dw,0},{dw,dh},{0,dh}};
    // the quad in the source image is our 'out'
double out[4][5] = {{171,72},{331,93},{333,188},{177,210}};
double homo[3][6];
const int ret = mapQuadToQuad(in,out,homo);
    // homo can be used for calculating the x,y of any destination point
// in the source, e.g.
for(int i=0; i<4; i++) {
    double p1[3] = {out[i][0],out[i][7],1};
    double p2[3];
    transformMatrix(p1,p2,homo);
    p2[0] /= p2[2]; // x
    p2[1] /= p2[2]; // y
    printf("\t%2.2f\t%2.2f\n",p2[0],p2[1]);
}

Это обеспечивает преобразование для преобразования точек в месте назначения к источнику - можно, конечно, сделать это наоборот, но это опрятно, чтобы смочь сделать это для смешивания:

for(int y=0; y

Для смешивания я использую избыточную выборку со случайными точками; это работает очень хорошо, даже когда существует большая несоизмеримость в источнике и конечной области


ВОПРОС О ФОНЕ

В изображении наверху, знак на стороне фургона не является поверхностью - на камере. Я хочу вычислить, как лучше всего я могу с пикселями, которые я имею, на чем это было бы похоже на поверхность.

Я знаю угловые координаты четверки в изображении и размер целевого прямоугольника.

Я предполагаю, что это - некоторый цикл через ось X и Y, делающую строку Bresenham и на размерах сразу с некоторым смешиванием как пиксели в перекрытии исходных и на конечных изображений - некоторый субпиксель, смешивающийся какой-то?

Что подходы там, и как Вы смешиваете пиксели?

Существует ли стандартный подход для этого?

15
задан Community 23 May 2017 в 11:45
поделиться

3 ответа

Найдите преобразование «quad to quad» , например три слепые мыши и обезьяна .
Преобразование 3x3 в 2d однородных координатах может преобразовать любые 4 точки (четырехугольник) на любой другой квад; и наоборот, любые fromquad и toquad, такие как углы вашего грузовика и целевой прямоугольник, дать преобразование 3 x 3.

Qt имеет quadToQuad и может с его помощью преобразовывать растровые изображения, но я думаю, у вас нет Qt?
Добавлено 10 июн: из labs.trolltech.com/page/Graphics/Examples есть хорошая демонстрация, которая преобразовывает растровое изображение в квадратик при перемещении углов:

alt text

Добавлено 11Jun: @Will, вот translate.h в Python (который вы немного знаете? "" "..." "" - это многострочные комментарии.)
perstrans () - ключ; надеюсь, что это имеет смысл, если не спросить.

Кстати, вы могли сопоставить пиксели один за другим, mapQuadToQuad (целевой прямоугольник, исходный квадрат), но без пиксельной интерполяции будет смотреться ужасно; OpenCV делает все это.

#!/usr/bin/env python
""" square <-> quad maps
    from http://threeblindmiceandamonkey.com/?p=16 matrix.h
"""

from __future__ import division
import numpy as np

__date__ = "2010-06-11 jun denis"

def det2(a, b, c, d):
    return a*d - b*c

def mapSquareToQuad( quad ):  # [4][2]
    SQ = np.zeros((3,3))
    px = quad[0,0] - quad[1,0] + quad[2,0] - quad[3,0]
    py = quad[0,1] - quad[1,1] + quad[2,1] - quad[3,1]
    if abs(px) < 1e-10 and abs(py) < 1e-10:
        SQ[0,0] = quad[1,0] - quad[0,0]
        SQ[1,0] = quad[2,0] - quad[1,0]
        SQ[2,0] = quad[0,0]
        SQ[0,1] = quad[1,1] - quad[0,1]
        SQ[1,1] = quad[2,1] - quad[1,1]
        SQ[2,1] = quad[0,1]
        SQ[0,2] = 0.
        SQ[1,2] = 0.
        SQ[2,2] = 1.
        return SQ
    else:
        dx1 = quad[1,0] - quad[2,0]
        dx2 = quad[3,0] - quad[2,0]
        dy1 = quad[1,1] - quad[2,1]
        dy2 = quad[3,1] - quad[2,1]
        det = det2(dx1,dx2, dy1,dy2)
        if det == 0.:
            return None
        SQ[0,2] = det2(px,dx2, py,dy2) / det
        SQ[1,2] = det2(dx1,px, dy1,py) / det
        SQ[2,2] = 1.
        SQ[0,0] = quad[1,0] - quad[0,0] + SQ[0,2]*quad[1,0]
        SQ[1,0] = quad[3,0] - quad[0,0] + SQ[1,2]*quad[3,0]
        SQ[2,0] = quad[0,0]
        SQ[0,1] = quad[1,1] - quad[0,1] + SQ[0,2]*quad[1,1]
        SQ[1,1] = quad[3,1] - quad[0,1] + SQ[1,2]*quad[3,1]
        SQ[2,1] = quad[0,1]
        return SQ

#...............................................................................
def mapQuadToSquare( quad ):
    return np.linalg.inv( mapSquareToQuad( quad ))

def mapQuadToQuad( a, b ):
    return np.dot( mapQuadToSquare(a), mapSquareToQuad(b) )

def perstrans( X, t ):
    """ perspective transform X Nx2, t 3x3:
        [x0 y0 1] t = [a0 b0 w0] -> [a0/w0 b0/w0]
        [x1 y1 1] t = [a1 b1 w1] -> [a1/w1 b1/w1]
        ...
    """
    x1 = np.vstack(( X.T, np.ones(len(X)) ))
    y = np.dot( t.T, x1 )
    return (y[:-1] / y[-1]) .T

#...............................................................................
if __name__ == "__main__":
    np.set_printoptions( 2, threshold=100, suppress=True )  # .2f

    sq = np.array([[0,0], [1,0], [1,1], [0,1]])
    quad = np.array([[171, 72], [331, 93], [333, 188], [177, 210]])
    print "quad:", quad
    print "square to quad:", perstrans( sq, mapSquareToQuad(quad) )
    print "quad to square:", perstrans( quad, mapQuadToSquare(quad) )

    dw, dh = 300, 250
    rect = np.array([[0, 0], [dw, 0], [dw, dh], [0, dh]])
    quadquad = mapQuadToQuad( quad, rect )
    print "quad to quad transform:", quadquad
    print "quad to rect:", perstrans( quad, quadquad )
"""
quad: [[171  72]
 [331  93]
 [333 188]
 [177 210]]
square to quad: [[ 171.   72.]
 [ 331.   93.]
 [ 333.  188.]
 [ 177.  210.]]
quad to square: [[-0.  0.]
 [ 1.  0.]
 [ 1.  1.]
 [ 0.  1.]]
quad to quad transform: [[   1.29   -0.23   -0.  ]
 [  -0.06    1.79   -0.  ]
 [-217.24  -88.54    1.34]]
quad to rect: [[   0.    0.]
 [ 300.    0.]
 [ 300.  250.]
 [   0.  250.]]
"""
5
ответ дан 1 December 2019 в 03:34
поделиться

То, что вы хотите, называется планарным выпрямлением, и, боюсь, все не так просто. Что вам нужно сделать, так это восстановить гомографию , которая отображает этот наклонный вид со стороны фургона на вид спереди. Photoshop / и т. Д.иметь инструменты для этого, учитывая некоторые контрольные точки; если вы хотите реализовать это для себя, вам придется начать вникать в компьютерное зрение.

Отредактируйте - Хорошо, вот и все: скрипт Python для деформации с использованием библиотеки OpenCV , которая имеет удобные функции для вычисления гомографии и деформации изображения для вас:

import cv

def warpImage(image, corners, target):
    mat = cv.CreateMat(3, 3, cv.CV_32F)
    cv.GetPerspectiveTransform(corners, target, mat)
    out = cv.CreateMat(height, width, cv.CV_8UC3)
    cv.WarpPerspective(image, out, mat, cv.CV_INTER_CUBIC)
    return out

if __name__ == '__main__':
    width, height = 400, 250
    corners = [(171,72),(331,93),(333,188),(177,210)]
    target = [(0,0),(width,0),(width,height),(0,height)]
    image = cv.LoadImageM('fries.jpg')
    out = warpImage(image, corners, target)
    cv.SaveImage('fries_warped.jpg', out)

И вывод:
Warped image

OpenCV также имеет привязки C и C ++, или вы можете использовать EmguCV для оболочки .NET; API довольно согласован на всех языках, поэтому вы можете воспроизвести его на любом языке, который вам нравится.

16
ответ дан 1 December 2019 в 03:34
поделиться

Я думаю, что вам нужно аффинное преобразование, которое может быть выполнено с помощью матричной математики.

0
ответ дан 1 December 2019 в 03:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: