Essayez de trouver des erreurs en utilisant OpenCV et Python.
Tout d'abord, créez une image pour trouver des erreurs. C'est difficile à faire, donc cette fois je vais emprunter l'image de la page web Illustration de recherche d'erreur d'entraînement cérébral 01 (débutant) ..
Et comme cette image est connectée verticalement à l'image A et à l'image B, elle est divisée en parties supérieure et inférieure. En plus de le diviser en deux, convertissez-le au format PNG pour le gérer avec OpenCV.
convert -crop 100%x50% image02.gif image02.png
Cela créera les fichiers divisés supérieur et inférieur iamge02-0.png et image02-1.png, et vous êtes prêt à partir.
Puisque les étiquettes sont écrites dans l'image comme "A" dans l'image supérieure et "B" dans l'image inférieure, les noms de fichier seront changés en image02A.png et image02B.png.
convert image02.gif image02.Vous pouvez le png et le diviser avec python.
```python
import cv2
img = cv2.imread('img/image02.png')
height, width, _ = img.shape
imageA = img[0:round(height/2), :]
imageB = img[round(height/2):, :]
cv2.imwrite('img/image02A.png', imageA)
cv2.imwrite('img/image02B.png', imageB)
Chargez une image A et une image B et essayez la détection de fonction.
def matchAB(fileA, fileB):
#Chargement des images
imgA = cv2.imread(fileA)
imgB = cv2.imread(fileB)
#Conversion de gris
grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)
#Extraction de la quantité de fonction AKAZE
akaze = cv2.AKAZE_create()
kpA, desA = akaze.detectAndCompute(grayA, None)
kpB, desB = akaze.detectAndCompute(grayB, None)
#Définition et imagerie BFMatcher
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(desB, desB)
matches = sorted(matches, key=lambda x: x.distance)
matched_image = cv2.drawMatches(imgA, kpA, imgB, kpB, matches, None, flags=2)
#afficher
plt.imshow(cv2.cvtColor(matched_image, cv2.COLOR_BGR2RGB))
plt.show()
Évidemment, la méthode ci-dessus marquerait les «endroits correspondants», mais ce n'est pas bon car il n'y a que 5 mauvais endroits.
Quelle est la recherche d'erreurs en premier lieu? En d'autres termes, lorsque les deux images sont superposées, les contours des images dessinées sur chacune peuvent être légèrement différents.
Considérant la possibilité que l'image A et l'image B soient légèrement désalignées, nous avons décidé de trouver la position où la fenêtre créée en divisant l'image A correspond le mieux à l'image B et de créer une image différente. fait.
def matchAB(fileA, fileB):
#Chargement des images
imgA = cv2.imread(fileA)
imgB = cv2.imread(fileB)
#Conversion de gris
grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)
#Obtenir la taille de l'image
height, width = grayA.shape
#Faire une image partielle et faire correspondre
result_window = np.zeros((height, width), dtype=imgA.dtype)
for start_y in range(0, height-100, 50):
for start_x in range(0, width-100, 50):
window = grayA[start_y:start_y+100, start_x:start_x+100]
match = cv2.matchTemplate(grayB, window, cv2.TM_CCOEFF_NORMED)
_, _, _, max_loc = cv2.minMaxLoc(match)
matched_window = grayB[max_loc[1]:max_loc[1]+100, max_loc[0]:max_loc[0]+100]
result = cv2.absdiff(window, matched_window)
result_window[start_y:start_y+100, start_x:start_x+100] = result
plt.imshow(result_window)
Avec cela, il s'est avéré qu'il y avait une position avec une grande différence.
Donc, cette fois, je vais prendre les coordonnées de la «position où il y a une différence» dans l'image de différence et essayer de la superposer sur l'image d'origine. Spécifiquement, les valeurs de coordonnées sont captées en extrayant le contour de la "position avec une différence", et un carré est dessiné sur l'image d'origine sur la base des valeurs de coordonnées.
def matchAB(fileA, fileB):
#Chargement des images
imgA = cv2.imread(fileA)
imgB = cv2.imread(fileB)
#Conversion de gris
grayA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)
#Obtenir la taille de l'image
height, width = grayA.shape
#Faire une image partielle et faire correspondre
result_window = np.zeros((height, width), dtype=imgA.dtype)
for start_y in range(0, height-100, 50):
for start_x in range(0, width-100, 50):
window = grayA[start_y:start_y+100, start_x:start_x+100]
match = cv2.matchTemplate(grayB, window, cv2.TM_CCOEFF_NORMED)
_, _, _, max_loc = cv2.minMaxLoc(match)
matched_window = grayB[max_loc[1]:max_loc[1]+100, max_loc[0]:max_loc[0]+100]
result = cv2.absdiff(window, matched_window)
result_window[start_y:start_y+100, start_x:start_x+100] = result
#Extrayez le contour de l'image de différence créée à la suite de la mise en correspondance et placez-la dans un carré
_, result_window_bin = cv2.threshold(result_window, 127, 255, cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(result_window_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
imgC = imgA.copy()
for contour in contours:
min = np.nanmin(contour, 0)
max = np.nanmax(contour, 0)
loc1 = (min[0][0], min[0][1])
loc2 = (max[0][0], max[0][1])
cv2.rectangle(imgC, loc1, loc2, 255, 2)
#Afficher l'image
plt.subplot(1, 3, 1), plt.imshow(cv2.cvtColor(imgA, cv2.COLOR_BGR2RGB)), plt.title('A'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 2), plt.imshow(cv2.cvtColor(imgB, cv2.COLOR_BGR2RGB)), plt.title('B'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 3, 3), plt.imshow(cv2.cvtColor(imgC, cv2.COLOR_BGR2RGB)), plt.title('Answer'), plt.xticks([]), plt.yticks([])
plt.show()
L'image est petite et difficile à voir, mais il semble que 5 erreurs peuvent être suggérées sauf pour la partie de l'étiquette avec A ou B en haut à gauche.
Il s'est avéré qu'il était possible de résoudre le quiz de recherche d'erreur en créant une image de différence à l'aide d'OpenCV.