Ответы пользователя по тегу OpenCV
  • Как накладывать изображения в python?

    Vindicar
    @Vindicar
    RTFM!
    Т.е. если переформулировать вопрос:
    Есть два изображения (A и B) с одинаковым набором маркеров. Нужно трансформировать изображение B так, чтобы его маркеры совпали по положению с маркерами изображения A, а потом наложить результат на изображение A.
    Я так понял?

    Если да, то это делается примерно так.
    1. Формируешь два массива координат - маркеры на изображениях A и B. Как - зависит от типа маркеров, но порядок должен быть одинаковым в обоих массивах. Форма (shape) массивов должна быть (N, 1, 2), где последний индекс отвечает за x или y координату, а N - число маркеров.
    2. Вызываешь
    homography, ptmask = cv2.findHomography(arrayB, arrayA, cv2.RANSAC)
    .
    homography будет матрицей проективного преобразования - как повернуть маркеры B, чтобы они легли на маркеры A. ptmask будет содержать сведения о том, какие пары точек удалось совместить.
    3. Делаешь вызов cv2.warpPerspective(), чтобы повернуть изображение B согласно матрице homography. Параметр размера должен быть таким чтобы второе изображение точно уместилось вместе с первым. Например, можно заранее создать большое изображение по размеру.
    4. Делаешь совмещение. Используешь cv2.PerspectiveTransform(), чтобы понять, где на итоговом изображении будут углы изображения B, делаешь cv2.fillPoly() чтобы создать бинарную маску для наложения. В маске белый пиксель будет означать "сюда поместить пиксель из повернутого B", а черный - "оставить пиксель как есть". Используешь эту маску, чтобы выполнить наложение.

    Пример кода и исходных данных - не совсем то, что тебе нужно, но идею передаст, я надеюсь.
    Ответ написан
  • Как работают Каскады Хаара в OpenCV?

    Vindicar
    @Vindicar
    RTFM!
    «Признак Хаара» это прямоугольный фильтр, разделенный на две области – светлую и темную. Данный фильтр накладывается на некоторую область изображения (окно). Значением (откликом) признака является сумма яркостей пикселей изображения в светлой области минус сумма яркостей пикселей в темной области. Если эта разность превышает некоторый порог, то мы считаем, что данный фильтр дал отклик в данном месте изображения.
    Это примитивный признак-классификатор. При обучении классификатора Хаара с помощью алгоритма бустинга набор таких примитивных классификаторов складывается в один составной классификатор. Но такой классификатор либо работает долго, либо даёт много ложных срабатываний. Даже шанс в 0,01% - это много, учитывая сколько возможнных окон (возможных позиций лица) может быть на изображении.
    Поэтому использует принцип "каскада внимания". Формируется цепочка из нескольких составных классификаторов таким образом, чтобы каждый последующий отсеивал как можно больше отрицательных примеров, но при этом пропускал все или почти все положительные (уровень обнаружения >95%). Это позволяет ограничиться вычислением сравнительно быстрых и простых составных классификаторов для подавляющего большинства окон на изображении.

    Под конец несколько близлежащих окон могут быть слиты в одно с помощью non-maximum suppression. Это нужно, так как лицо может попасть сразу в несколько соседних окон, чуть смещённых относительно друг друга.
    Если в итоге у нас есть отклики, то мы знаем позиции и размеры возможных лиц на изображении. А дальше уже эвристика на основании этих сведений. Например, если нам нужен крупный план, то мы можем отвергнуть изображение, если наибольшее лицо занимает менее 75% площади изображения.
    Ответ написан
  • Python cv2 как перести многомерный массив в картинку?

    Vindicar
    @Vindicar
    RTFM!
    src = [['255', '255', '255', '190', '190', '160', '76', '45', '78'],
    ['255', '255', '255', '190', '190', '160', '76', '45', '78'],
    ['255', '255', '255', '190', '190', '160', '76', '45', '78']]
    
    int_src = [ list(map(int, row)) for row in src ]
    red = [ row[0::3] for row in src ] #подразумеваю, что у тебя составляющие идут в порядке RGB
    green = [ row[1::3] for row in src ]
    blue = [ row[2::3] for row in src ]
    image = cv2.merge((blue, green, red)) #opencv по умолчанию хранит изображения в BGR, а не RGB
    Ответ написан
    Комментировать
  • Вопрос к знатокам opencv?

    Vindicar
    @Vindicar
    RTFM!
    Сами - нет. Подбери один раз значение под свою задачу, и оставь его.
    scaleFactor - это шаг масштабирования при поиске объектов разного видимого размера.
    Чем он ближе к 1, тем более мелкие шаги делает алгоритм, тем больше этих шагов, тем дольше обрабатывается изображение. Чем он больше, тем быстрее обработка - но в то же время лицо "промежуточного" размера между парой шагов может быть потеряно.

    Следует учесть, что лицо может "теряться" не только из-за этого параметра, но и из-за множества других факторов.
    Ответ написан
    Комментировать
  • Как найти одно изображение на другом изображении?

    Vindicar
    @Vindicar
    RTFM!
    Терминология для гуглинга: "Локализация объекта методами компьтерного зрения".
    В качестве инструментария можешь использовать opencv. Для питона это pip пакет python-opencv (импортируется под именем cv2).

    Чтобы обойти проблему цвета, переведи входное изображение в оттенки серого, и потом, если оптребуется, добавь пороговое преобразование, чтобы оставить только чёрный и белый.

    Подходы существуют разные. Если не требуется дикоре быстродействие, то можно использовать детектор SIFT.
    Тогда у тебя будет алгоритм вида:
    0. Создаёшь детектор (функция cv2.SIFT.create()) и матчер (можно cv2.BFMatcher(), он тормознутый но простой в использовании).
    1. Грузишь образец искомого объекта и преобразуешь изображения (палитра серого, и т.п.)
    2. Вызываешь метод детектора .detectAndCompute(), чтобы получить найденные особые точки (углы и т.п.) и их описание.
    3. Повторяешь шаги 1,2 для анализируемого изображения (сцены).
    4. У матчера вызываешь метод .knnMatch() c n=2. Это даст тебе 2 лучших совпадения между образцом и сценой по каждой особой точке.
    5. Можно просто брать лучшее совпадение, а можно отсеять те особые точки, у которых два ближайших совпадения слишком похожи - они отсеялись.
    Так или иначе, у тебя должен получиться список пар точек вида "точка на образце - найденная похожая точка на сцене".
    6. Используешь функцию cv2.findHomography() или одну из родственных ей, чтобы найти матрицу преобразования. Грубо говоря, она позволит пересчитать позицию пикселя на изображении образца в позицию пикселя на изображении сцены.
    Примерно так, если представить это наглядно (чтобы получить такую картинку, нужно еще несколько шагов, но она передаёт идею).
    homography_findobj.jpg
    7. Дальше ты можешь использовать эту матрицу как хочешь. Например, возьми координаты центра объекта на изображении-образце, и используй её вместе с cv2.perspectiveTransform(), чтобы найти, где на сцене координаты точки центра объекта. Взяв ещё точку (в углу или на краю), сможешь найти ориентацию.

    Проблема в том, что этот подход работает ТОЛЬКО если в сцене не более одного похожего объекта.

    Код не привожу, набросай черновик сам, тогда можно будет его обсудить и подкорректировать. Если что, в сети можно много найти инфы по использованию opencv для решения этой задачи.
    Ответ написан
    4 комментария
  • Как обработать изображение через CV2?

    Vindicar
    @Vindicar
    RTFM!
    Непонятно, что именно ты пытаешься сделать.
    Если просто перевести скриншот в другое цветовое пространство, то вот этих двух строчек
    image = pyautogui.screenshot(region=(514, 495, 264, 12))
    image = cv2.cvtColor(np.array(image), cv2.COLOR_BGR2GRAY)
    должно хватить.
    Дальше crop лучше делать средствами cv2, благо для этого достаточно средств numpy-массивов (а именно так cv2 хранит изображения).
    Ответ написан
  • Определение количества квадратов с пересечением?

    Vindicar
    @Vindicar
    RTFM!
    Размер квадрата известен? Используй скользящее окно.
    Вырезай поочерёдно все фрагменты изображения такого размера, если оно целиком чёрное - то фиксируем квадрат в этой позиции.

    Могут быть ложные срабатывания, если два перекрывающихся квадрата расположены идеально на одной вертикали/горизонтали. Тут нужно искать все срабатывания в этой области, и выбирать крайнее левое/правое или нижнее/верхнее.
    Ответ написан
    Комментировать
  • При выводе изображения по CSV появляется ошибка. Что не так в моем коде?

    Vindicar
    @Vindicar
    RTFM!
    img = cv2.imread('data/first/{}'.format(img_name))
    mask = cv2.imread('data/mas/{}'.format(img_name))

    Во-первых, стоит указать вторым параметром cv2.IMREAD_COLOR.
    Во-вторых, проверь, что в итоге в img и mask.
    В случае ошибки imread() молча возвращает None, а не кидает исключение.
    Ответ написан
    3 комментария
  • Не могу понять в чем ошибка?

    Vindicar
    @Vindicar
    RTFM!
    face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
    cv2.error: OpenCV(4.5.1) /tmp/pip-req-build-ms668fyv/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

    "Assertion failed" значит, не прошла впроверка входных данных.

    "!_src.empty()" подсказывает, что входное изображение должно быть не пустым - а у тебя, выходит, пустое.

    Ты делаешь frame[startY:endY, startX:endX] - вставь проверку, что startY != endY, а startX != endX.
    Кроме того, стоит проверить, что ты действительно получил кадр через frame = vs.read().
    Ответ написан