首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用vips实现透视变换

使用vips实现透视变换
EN

Stack Overflow用户
提问于 2020-12-18 16:29:55
回答 1查看 82关注 0票数 1

我正在尝试在Go中使用vips实现一个透视图转换。我使用opencv的GetPerspectiveTransform方法来计算一个变换矩阵,然后计算一个地图图像,如下所示

代码语言:javascript
复制
func DistortPerspective(ref *vips.ImageRef, tiepoints []float64) {
    T := createTransform(tiepoints)

    // make an index image where pixels have the value of their (x, y) coordinates
    index, err := vips.XYZ(ref.Width(), ref.Height())
    if err != nil {
        logger.Debug(nil, err)
    }

    i0, err := index.Copy()
    if err != nil {
        logger.Debug(nil, err)
    }
    i1, err := index.Copy()
    if err != nil {
        logger.Debug(nil, err)
    }
    err = i0.ExtractBand(0, 1)
    if err != nil {
        logger.Debug(nil, err)
    }
    err = i1.ExtractBand(1, 1)
    if err != nil {
        logger.Debug(nil, err)
    }

    T00 := float64(T.GetFloatAt(0, 0))
    T01 := float64(T.GetFloatAt(0, 1))
    T02 := float64(T.GetFloatAt(0, 2))

    T10 := float64(T.GetFloatAt(1, 0))
    T11 := float64(T.GetFloatAt(1, 1))
    T12 := float64(T.GetFloatAt(1, 2))

    T20 := float64(T.GetFloatAt(2, 0))
    T21 := float64(T.GetFloatAt(2, 1))
    T22 := float64(T.GetFloatAt(2, 2))

    // i0 * T[0,0]
    i0xT00 := linear(i0, T00, 0)

    // i1 * T[0,1] + T[0,2]
    i1xT01_T02 := linear(i1, T01, T02)

    // i0 * T[1,0]
    i0xT10 := linear(i0, T10, 0)

    // i1 * T[1,1] + T[1,2]
    i1xT11_T12 := linear(i1, T11, T12)

    //i[0] * T[0,0] + i[1] * T[0,1] + T[0,2]
    i0xT00_i1xT01_T02 := add(i0xT00, i1xT01_T02)

    //i[0] * T[1,0] + i[1] * T[1,1] + T[1,2]
    i0xT10_i1xT11_T12 := add(i0xT10, i1xT11_T12)

    //i[0] * T[2,0]
    i0xT20 := linear(i0, T20, 0)

    //i[1] * T[2,1] + T[2,2]
    i1xT21_T22 := linear(i1, T21, T22)

    //i[0] * T[2,0] + i[1] * T[2,1] + T[2,2]
    i0xT20_i1xT21_T22 := add(i0xT20, i1xT21_T22)

    //x = (i[0] * T[0,0] + i[1] * T[0,1] + T[0,2]) / (i[0] * T[2,0] + i[1] * T[2,1] + T[2,2])
    x := divide(i0xT00_i1xT01_T02, i0xT20_i1xT21_T22)

    //y = (i[0] * T[1,0] + i[1] * T[1,1] + T[1,2]) / (i[0] * T[2,0] + i[1] * T[2,1] + T[2,2])
    y := divide(i0xT10_i1xT11_T12, i0xT20_i1xT21_T22)

    //# join up x and y as a map image
    mapimage := bandjoin(x, y)

    //transform the original image
    err = ref.Mapim(mapimage)
    if err != nil {
        logger.Debug(nil, err)
    }
}

然而,作为结果的图像是错误的。我使用这个堆栈溢出答案作为参考How to perform perspective distort transformation in VIPS?,在我看来opencv WarpPerspective方法做了一些类似的事情,所以我认为使用opencv来计算变换系数是可行的。

EN

回答 1

Stack Overflow用户

发布于 2020-12-22 19:03:38

答案是两方面的。

首先,使用返回正确float64的GetDoubleAt(row int, col int)方法,而不是返回float32的GetFloatAt(row int, col int)。不知怎么的,转换把数字搞乱了。

其次,在计算变换矩阵的方法中,在GetPerspectiveTransform调用中,源集合和目标集合应该是反转的。这是因为opencv的WarpPerspective方法隐式地求逆矩阵,而这个实现不是。

代码语言:javascript
复制
func createTransform(distortion []float64) gocv.Mat {
    srcSet := []image.Point{
        {X: int(distortion[0]), Y: int(distortion[1])},
        {X: int(distortion[4]), Y: int(distortion[5])},
        {X: int(distortion[8]), Y: int(distortion[9])},
        {X: int(distortion[12]), Y: int(distortion[13])},
    }
    dstSet := []image.Point{
        {X: int(distortion[2]), Y: int(distortion[3])},
        {X: int(distortion[6]), Y: int(distortion[7])},
        {X: int(distortion[10]), Y: int(distortion[11])},
        {X: int(distortion[14]), Y: int(distortion[15])},
    }
    return gocv.GetPerspectiveTransform(dstSet, srcSet)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65353840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档