13 votes

Comment supprimer la partie noire de l'image ?

J'ai assemblé deux images en utilisant des fonctions OpenCV et C++. Je suis maintenant confronté à un problème : l'image finale contient une grande partie noire.

L'image finale doit être un rectangle contenant la partie efficace. Mon image est la suivante :

enter image description here

Comment supprimer la partie noire ?

24voto

Abid Rahman K Points 18045

mevatron La réponse de M. K. est une façon de minimiser la quantité de zones noires tout en conservant l'intégralité de l'image.

Une autre option consiste à supprimer toute la zone noire, ce qui entraîne la perte d'une partie de l'image, mais le résultat sera une image rectangulaire soignée. Voici le code Python.

Ici, vous trouverez trois coins principaux de l'image comme ci-dessous :

enter image description here

J'ai marqué ces valeurs. (1,x2), (x1,1), (x3,y3) . Il est basé sur l'hypothèse que votre image commence à (1,1).

Code :

Les premières étapes sont les mêmes que mevatron 's. Flouter l'image pour éliminer le bruit, seuiller l'image, puis trouver les contours.

import cv2
import numpy as np

img = cv2.imread('office.jpg')
img = cv2.resize(img,(800,400))

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray,3)

ret,thresh = cv2.threshold(gray,1,255,0)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

Trouvez maintenant le contour le plus large qui correspond à votre image. Il s'agit d'éviter tout bruit éventuel (il est très probable qu'il n'y en ait pas). Vous pouvez également utiliser mevatron La méthode de l

max_area = -1
best_cnt = None

for cnt in contours:

    area = cv2.contourArea(cnt)
    if area > max_area:
        max_area = area
        best_cnt = cnt

L'approximation du contour permet de supprimer les points inutiles dans les valeurs de contour trouvées, tout en préservant toutes les valeurs d'angle.

approx = cv2.approxPolyDP(best_cnt,0.01*cv2.arcLength(best_cnt,True),True)

Il s'agit maintenant de trouver les coins.

Tout d'abord, nous trouvons (x3,y3). C'est le point le plus éloigné. Donc x3*y3 sera très importante. Nous trouvons donc les produits de toutes les paires de points et sélectionnons la paire ayant le produit le plus élevé.

far = approx[np.product(approx,2).argmax()][0]

Suivant (1,x2). C'est le point où le premier élément est un, puis le deuxième élément est le maximum.

ymax = approx[approx[:,:,0]==1].max()

Suivant (x1,1). C'est le point où le deuxième élément est 1, alors le premier élément est maximum.

xmax = approx[approx[:,:,1]==1].max()

Nous trouvons maintenant la minimum values in (far.x,xmax) and (far.y, ymax)

x = min(far[0],xmax)
y = min(far[1],ymax)

Si vous dessinez un rectangle avec (1,1) et (x,y), vous obtenez le résultat suivant :

enter image description here

Vous recadrez donc l'image pour corriger la zone rectangulaire.

img2 = img[:y,:x].copy()

Voici le résultat :

enter image description here

See, the problem is that you lose some parts of the stitched image.

9voto

mevatron Points 8271

Vous pouvez le faire avec seuil , findContours y boundingRect .

Voici donc un rapide script qui fait cela avec l'interface python.

stitched = cv2.imread('stitched.jpg', 0)
(_, mask) = cv2.threshold(stitched, 1.0, 255.0, cv2.THRESH_BINARY);

# findContours destroys input
temp = mask.copy()
(contours, _) = cv2.findContours(temp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# sort contours by largest first (if there are more than one)
contours = sorted(contours, key=lambda contour:len(contour), reverse=True)
roi = cv2.boundingRect(contours[0])

# use the roi to select into the original 'stitched' image
stitched[roi[1]:roi[3], roi[0]:roi[2]]

Voici à quoi cela ressemble : enter image description here

NOTE : Le tri n'est peut-être pas nécessaire avec l'imagerie brute, mais l'utilisation de l'image compressée a provoqué l'apparition d'artefacts de compression lors de l'utilisation d'un seuil bas, c'est pourquoi j'ai effectué un post-traitement avec tri.

J'espère que cela vous aidera !

0voto

Hakan Serce Points 6705

Vous pouvez utiliser des contours actifs (ballons/serpents) pour sélectionner avec précision la zone noire. Une démonstration est disponible aquí . Les contours actifs sont disponibles dans OpenCV. cvSnakeImage .

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