5 votes

Pixels excentrés dans OpenCV warpPerspective()

Mon application nécessite de mapper un quadrilatère sur un autre quadrilatère. Aucun des deux n'est un rectangle.

Cependant, le résultat obtenu avec warpPerspective() est toujours un rectangle. J'ai essayé de modifier le paramètre "outlier" avec différentes valeurs pour éviter que les pixels extérieurs au quadrilatère déformé n'apparaissent dans l'image de destination mais rien ne fonctionne. Ce que je veux, c'est un quadrilatère déformé avec les pixels à l'extérieur du quadrilatère déformé définis sur la transparence.

Comment puis-je y arriver ?

Alternativement, y a-t-il un moyen simple de masquer la région à l'extérieur d'un quadrilatère dans OpenCV afin que je puisse copier seulement le quadrilatère vers une autre image ?

Si cela est pertinent, j'utilise la liaison Python à OpenCV.

Voici mon code actuel :

def warpImage(image, corners, target, width, height):
    mat = cv2.getPerspectiveTransform(corners, target)
    out = numpy.zeros(shape=(width, height), dtype="uint8")
    out = cv2.warpPerspective(image, mat, (width,height), out, cv2.INTER_CUBIC)
    return out

Les coins et la cible sont tous deux des quadrilatères non rectangulaires. Cependant, la sortie est un rectangle de largeurxhauteur complet. Aucun des pixels n'est noir ou transparent. Au lieu de cela, ce sont des pixels de l'image à la fois à l'intérieur et à l'extérieur du quadrilatère des coins. Je ne veux que ceux à l'intérieur.

0voto

Kevin Jardine Points 107

La meilleure option que j'ai trouvée consiste à parcourir les pixels et à copier ceux du quadrisphère déformé dans un tableau de remappage en utilisant la fonction matplotlib pnpoly(), comme ceci :

import matplotlib.nxutils as nx 

def warpImage(image, corners, target, width, height, x0, y0, remap):
    mat = cv2.getPerspectiveTransform(corners, target)
    out = cv2.warpPerspective(image, mat, (width,height), flags=cv2.INTER_CUBIC)
    for x in range(0,width):
        for y in range(0,height):
            if nx.pnpoly(x,y,target) == 1:
                for i in range(0,3):
                    remap[y+y0,x+x0,i] = out[y,x,i]

    return remap

Je parcours tous les quads dans l'image et j'accumule les versions transformées dans remap.

Devoir accéder à chaque pixel n'est pas très efficace mais heureusement, il s'agit d'une transformation ponctuelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X