如何在opencv中应用三点三角形渐变?

问题描述 投票:0回答:2

说我们有一个像this one:的Delaunay三角剖分

enter image description here

fillConvexPolygetVoronoiFacetList产生

[里面有可以通过getTriangleList获得的三角形。我想画Delaunay三角剖分像是由三角形组成的平滑渐变图像,如下所示:

enter image description here

如何在opencv中做这样的事情?

python c++ opencv gradient triangulation
2个回答
1
投票

这是在Python / OpenCV中执行此操作的方法,但是它将比我之前介绍的Python / Wand版本慢,因为它必须循环并求解重心坐标的每个像素处的线性最小二乘方程。

import cv2
import numpy as np

# References: 
# https://stackoverflow.com/questions/31442826/increasing-efficiency-of-barycentric-coordinate-calculation-in-python
# https://math.stackexchange.com/questions/81178/help-with-cramers-rule-and-barycentric-coordinates

# create black background image
result = np.zeros((500,500,3), dtype=np.uint8)

# Specify (x,y) triangle vertices
a = (250,100)
b = (100,400)
c = (400,400)

# Specify colors
red = (0,0,255)
green = (0,255,0)
blue = (255,0,0)

# Make array of vertices
# ax bx cx
# ay by cy
#  1  1  1
triArr = np.asarray([a[0],b[0],c[0], a[1],b[1],c[1], 1,1,1]).reshape((3, 3))

# Get bounding box of the triangle
xleft = min(a[0], b[0], c[0])
xright = max(a[0], b[0], c[0])
ytop = min(a[1], b[1], c[1])
ybottom = max(a[1], b[1], c[1])

# loop over each pixel, compute barycentric coordinates and interpolate vertex colors
for y in range(ytop, ybottom):

    for x in range(xleft, xright):

        # Store the current point as a matrix
        p = np.array([[x], [y], [1]])

        # Solve for least squares solution to get barycentric coordinates
        (alpha, beta, gamma) = np.linalg.lstsq(triArr, p, rcond=-1)[0]

        # The point is inside the triangle if all the following conditions are met; otherwise outside the triangle
        if alpha > 0 and beta > 0 and gamma > 0:
            # do barycentric interpolation on colors
            color = (red*alpha + green*beta + blue*gamma)
            result[y,x] = color

# show results
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('barycentric_triange.png', result)

结果:

enter image description here


1
投票

在OpenCV中,我不认为有任何现成的功能可以做到这一点。您将必须遍历图像中的每个像素并计算重心(区域)插值。例如,请参见https://codeplea.com/triangular-interpolation

但是,在Python / Wand(基于ImageMagick)中,您可以执行以下操作:

import numpy as np
from wand.image import Image
from wand.color import Color
from wand.drawing import Drawing
from wand.display import display

# define vertices of triangle
p1 = (250, 100)
p2 = (100, 400)
p3 = (400, 400)

# define barycentric colors and vertices
colors = {
    Color('RED'): p1,
    Color('GREEN1'): p2,
    Color('BLUE'): p3
}

# create black image
black = np.zeros([500, 500, 3], dtype=np.uint8)

with Image.from_array(black) as img:
    with img.clone() as mask:
        with Drawing() as draw:
            points = [p1, p2, p3]
            draw.fill_color = Color('white')
            draw.polygon(points)
            draw.draw(mask)
            img.sparse_color('barycentric', colors)
            img.composite_channel('all_channels', mask, 'multiply', 0, 0)   
            img.format = 'png'
            img.save(filename='barycentric_image.png')
            display(img)

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.