Как найти одинаковую рентабельность инвестиций для одного и того же текста с разными цветами?

#python #opencv #roi

#python #opencv #roi

Вопрос:

Я пытаюсь найти ROI на этих двух изображениях:

введите описание изображения здесь

введите описание изображения здесь

Я использую этот код для изображения № 1:

 image_1 = image1
corr1 = []
gray = cv2.cvtColor(image_1, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (1,1), 1)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,10)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilate = cv2.dilate(thresh, kernel, iterations=3)

cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
ROI_numbers1 = 0
ROI1 = []
for c in cnts:
    area = cv2.contourArea(c)
    if area > 5:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(image_1, (x, y), (x   w, y   h), (0,255,0), 1)
        ROI1.append(image_1[y:y h, x:x w])
        corr1.append([y,y h, x,x w])
        ROI_numbers1  = 1
 

И этот код для изображения #2:

 image_2 = image2
corr2 = []
gray = cv2.cvtColor(image_2, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (1,1), 1)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,10)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilate = cv2.dilate(thresh, kernel, iterations=3)

cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
ROI_numbers2 = 0
ROI2 = []
for c in cnts:
    area = cv2.contourArea(c)
    if area > 5:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(image_2, (x, y), (x   w, y   h), (0,255,0), 1)
        ROI2.append(image_2[y:y h, x:x w])
        corr2.append([y,y h, x,x w])
        ROI_numbers2  = 1
 

После использования OpenCV для отображения ROI, я получаю следующее:

введите описание изображения здесь

Почему область ROI для синего текста на изображении # 1 меньше, чем для белого текста на изображении # 2?

Комментарии:

1. @HansHirse можете ли вы предложить какое-то решение, если это возможно.

Ответ №1:

При преобразовании изображений в оттенки серого вы получите разные значения серого для белого и синего текста. Таким образом, cv2.GaussianBlur это даст разные результаты, и следующие cv2.adaptiveThreshold тоже. В итоге найденные контуры отличаются, следуя ROI.

Не преобразовывайте здесь в оттенки серого! В вашем исходном трехканальном изображении замаскируйте все, что не является фоном, то есть сплошным серым (53, 53, 53) цветом. Эта маска заменяет вашу thresh . Оттуда вы можете использовать свою существующую реализацию.

Вот минимальный пример, чтобы проверить, совпадают ли результирующие ограничивающие прямоугольники (ROI):

 import cv2
import numpy as np


def cnts_from_image(image):
    thresh = (~np.all(image == (53, 53, 53), axis=2)).astype(np.uint8) * 255
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    dilate = cv2.dilate(thresh, kernel, iterations=3)
    cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    return cnts


rects_white = [cv2.boundingRect(c) for c in cnts_from_image(cv2.imread('white_text.png'))]
rects_blue = [cv2.boundingRect(c) for c in cnts_from_image(cv2.imread('blue_text.png'))]

print('All rectangles identical:', np.all([rw == rb for rw, rb in zip(rects_white, rects_blue)]))
# All rectangles identical: True
 
 ----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
NumPy:         1.20.2
OpenCV:        4.5.1
----------------------------------------
 

Комментарии:

1. Его работа хороша для серого фона, но не для любого другого. Должен ли я вручную вводить разные значения в (53, 53, 53), чтобы проверить наличие разных цветов фона?

2. @animesh Точно, вам нужно адаптировать это значение RGB / BGR в соответствии с цветом фона.