2 votes

J'essaie de remplacer les cellules noircies dans le tableau ci-dessous par une autre image avec Python OpenCV. Comment puis-je faire cela ?

J'ai le code suivant mais pour une raison quelconque, mon code ne détecte pas les régions noires. Je pensais que le fait de fixer le seuil à 0,5 lui permettrait de se limiter aux régions noires, mais je n'y parviens pas. Ci-dessous se trouve l'image avec les zones noires et l'image avec laquelle je veux remplacer les zones noires. Comment puis-je limiter la détection des contours aux seules zones noires ? Je veux faire cela pour n'importe quelle version de ce tableau exact qui peut avoir seulement 1 colonne de cellules noircies ou 2 ou n'importe quel nombre de zones.

enter image description here

enter image description here

orig_img = cv2.imread(r'C:/Users/15127/Downloads/download (1) (1).png')

cv2.imshow('image', orig_img)

# Define the threshold for identifying blacked-out areas
thresh = 0.5

replacement_img = cv2.imread(r'C:/Users/15127/Downloads/tablereplace.png')

# Convert the original image to grayscale
gray = cv2.cvtColor(orig_img, cv2.COLOR_BGR2GRAY)

# Threshold the grayscale image to identify blacked-out areas
mask = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY_INV)[1]

# Find contours around the blacked-out areas in the mask
contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Loop over the contours and draw rectangles around the blacked-out areas in the original image
for contour in contours:
    # Get the bounding box of the blacked-out area
    x, y, w, h = cv2.boundingRect(contour)
    cv2.rectangle(orig_img, (x, y), (x+w, y+h), (0, 0, 255), 2)
    # Draw a red rectangle around the blacked-out area in the original image
    if orig_img[y:y + h, x:x + w].shape[0] == 104 and x * w * y > 100000:
        replacement_roi = cv2.resize(replacement_img, dsize=(w, h), interpolation=cv2.INTER_CUBIC)
        orig_img[y:y + h, x:x + w] = replacement_roi

cv2.imshow('image', orig_img)

J'ai essayé d'utiliser le code ci-dessus pour détecter les contours mais il ne semble pas fonctionner pour se limiter aux régions noircies.

4voto

Rotem Points 3340

Le problème principal est que les lignes noires du tableau relient les rectangles noirs et forment un grand contour.

Pour la suppression des lignes, nous pouvons appliquer ouverture morphologique au masque.
Appliquez l'ouverture dans le sens vertical pour éliminer les lignes horizontales, puis appliquez l'ouverture dans le sens horizontal pour éliminer les lignes verticales :

mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((5, 1), np.uint8))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((1, 5), np.uint8))

Il se peut également que nous devions modifier la condition if orig_img[y:y + h, x:x + w].shape[0] == 104 and x * w * y > 100000 à quelque chose comme if w * h > 1000: .


Exemple de code :

import cv2
import numpy as np

#orig_img = cv2.imread(r'C:/Users/15127/Downloads/download (1) (1).png')
orig_img = cv2.imread('orig_image.png')
#cv2.imshow('image', orig_img)

# Define the threshold for identifying blacked-out areas
thresh = 0.5

#replacement_img = cv2.imread(r'C:/Users/15127/Downloads/tablereplace.png')
replacement_img = cv2.imread('tablereplace.png')

# Convert the original image to grayscale
gray = cv2.cvtColor(orig_img, cv2.COLOR_BGR2GRAY)

# Threshold the grayscale image to identify blacked-out areas
mask = cv2.threshold(gray, thresh, 255, cv2.THRESH_BINARY_INV)[1]

# Apply opening in the vertical direction and then in the horizontal direction - erasing the lines that connects the contours
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((5, 1), np.uint8))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((1, 5), np.uint8))

mask_img = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)

# Find contours around the blacked-out areas in the mask
#contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # Have contours inside contours, use RETR_TREE (RETR_EXTERNAL finds only the most outer contour) - not needed after opening

# Loop over the contours and draw rectangles around the blacked-out areas in the original image
for contour in contours:
    # Get the bounding box of the blacked-out area
    x, y, w, h = cv2.boundingRect(contour)    
    # Draw a red rectangle around the blacked-out area in the original image
    #if orig_img[y:y + h, x:x + w].shape[0] == 104 and x * w * y > 100000:
    if w * h > 1000:
        cv2.rectangle(mask_img, (x, y), (x+w, y+h), (255, 0, 0), 2)
        replacement_roi = cv2.resize(replacement_img, dsize=(w, h), interpolation=cv2.INTER_CUBIC)
        orig_img[y:y + h, x:x + w] = replacement_roi
        cv2.rectangle(orig_img, (x, y), (x+w, y+h), (0, 0, 255), 2)

cv2.imshow('image', orig_img)
cv2.imshow('mask_img', mask_img)
cv2.imshow('mask', mask)
cv2.waitKey()
cv2.destroyAllWindows()

mask après les opérations d'ouverture :
enter image description here

orig_img de la production :
enter image description here

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