Определение сходства изображений, когда изображения имеют различные факторы.Анализ изображений - PullRequest
0 голосов
/ 11 декабря 2018

Привет за прошедшую неделю (или больше) Я боролся с проблемой.

Сценарий:

Я разрабатываю приложение, которое позволитэксперт для создания рецепта, используя предоставленное изображение чего-то, что будет использоваться в качестве основы.Рецепт состоит из областей интересов.Цель программы - разрешить использовать ее не экспертам, предоставляя изображения, аналогичные оригиналу, и программное обеспечение перекрестно проверяет эти различные области интереса от изображения рецепта до предоставленного изображения.

Один сценарий варианта использования может бытьбанкноты.Эксперт выберет область на хорошем изображении подлинной банкноты, а затем пользователь предоставит программному обеспечению изображения банкнот, которые необходимо проверить.Таким образом, освещение и устройство захвата могут быть разными.
Я не хочу, чтобы вы, ребята, углублялись в природу сравнения банкнот, это еще один монстр, с которым нужно бороться, и я по большей части рассмотрел его.

Моя проблема:

Первоначально я сжимаю одно из двух изображений до размера меньшего.Так что теперь мы имеем дело с картинками одинакового размера.(На самом деле я выполняю сжатие в области, представляющей интерес, а не на всю картину, но это не должно иметь значения.)

Я пробовал и использовал разные методологии для сравнения этих частей, но у каждой из них были свои ограничения из-захарактер изображений.Освещенность может быть разной, при условии, что изображение может иметь какие-то загрязнения и т. Д.

Что я пробовал:

Простое сравнение сходства изображений с использованием RGB разница.

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

SSIM на изображениях RGB.

дал бы очень низкий процент сходства по всем каналам.

SSIM после использования фильтра sobel.

Снова низкий процент сходства.Я использовал SSIM из Scikit в Python и SSIM из OpenCV

Соответствие функции с Flann .

Не удалось найти хороший способ использовать обнаруженные совпадения для извлечения сходства.

По сути, я предполагаю, что мне нужно использовать различные методы и алгоритмы для достижения наилучшего результата.Моя интуиция говорит мне, что мне нужно будет объединить результаты сравнения RGB с методологией, которая будет:

  • Выполнить некоторую форму обнаружения края, такую ​​как sobel.
  • Сравните результаты на основе сопоставления формы или чего-то подобного.

Я новичок в области анализа изображений, и я также попытался найти способ сравнить, чистые продукты из представленных изображенийиспользуя среднее и стандартное вычисление из openCV, однако я либо сделал это неправильно, либо полученные результаты были в любом случае бесполезны.Я вычислил евклидово расстояние между векторами, полученными в результате вычисления среднего и стандартного значения, однако я не мог использовать результаты главным образом потому, что не мог видеть, как они связаны между изображениями.

Я не предоставляю код, который я использовал, во-первых, потому что я его отбросил, и, во-вторых, потому что я не ищу кодовое решение, а методологию или какое-то направление к учебному материалу.(Я уже прочитал кучу бумаг).Наконец, я не пытаюсь обнаружить похожие изображения, но, учитывая два изображения, извлекаю сходство между ними, пытаясь обойти небольшие различия, вызванные освещением или искажением бумаги и т. Д.

В заключение я хотел бы сказать, что я проверил всеметоды, предоставляя одно и то же изображение дважды, и я получал бы 100% -ное сходство, поэтому я не испортил его полностью.

Возможно ли то, что я пытаюсь сделать, без каких-либо обучающих наборов, чтобы научить программное обеспечение тому, чтоприемлемые варианты изображения?(Опять же, я понятия не имею, имеет ли это смысл: D)

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Хорошо, после некоторого копания, вот с чем я пришел:

#!/usr/bin/env
import numpy as np
import cv2
import sys
import matplotlib.image as mpimg
from skimage import io
from skimage import measure
import time

s = 0
imgA = cv2.imread(sys.argv[1])
imgB = cv2.imread(sys.argv[2])
#imgA = cv2.imread('imageA.bmp')
#imgB = cv2.imread('imageB.bmp')

imgA = cv2.cvtColor(imgA, cv2.COLOR_BGR2GRAY)
imgB = cv2.cvtColor(imgB, cv2.COLOR_BGR2GRAY)

ret,imgA = cv2.threshold(imgA,127,255,0)
ret,imgB = cv2.threshold(imgB,127,255,0)

imgAContours, contoursA, hierarchyA = cv2.findContours(imgA, cv2.RETR_TREE , cv2.CHAIN_APPROX_NONE)
imgBContours, contoursB, hierarchyB = cv2.findContours(imgB, cv2.RETR_TREE , cv2.CHAIN_APPROX_NONE)

imgAContours = cv2.drawContours(imgAContours,contoursA,-1,(0,0,0),1)
imgBContours = cv2.drawContours(imgBContours,contoursB,-1,(0,0,0),1)
imgAContours = cv2.medianBlur(imgAContours,5)
imgBContours = cv2.medianBlur(imgBContours,5)



#s = 100 * 1/(1+cv2.matchShapes(imgAContours,imgBContours,cv2.CONTOURS_MATCH_I2,0.0))
#s = measure.compare_ssim(imgAContours,imgBContours)
#equality = np.equal(imgAContours,imgBContours)
total = 0.0
sum = 0.0

for x in range(len(imgAContours)):
    for y in range(len(imgAContours[x])):
        total +=1
        t = imgAContours[x,y] == imgBContours[x,y]
        if t:
            sum+=1

s = (sum/total) * 100

print(s)

В основном я предварительно обработал два изображения настолько просто, насколько это возможно, затем я нахожу контуры.Теперь функция matchShapes из openCV не давала мне желаемых результатов.Поэтому я создаю два изображения, используя информацию из контуров, а затем применяю фильтр медианного размытия.

В настоящее время я делаю просто логическую проверку пиксель за пикселем.Однако я планирую изменить это в будущем, сделав его умнее.Вероятно, с некоторой математикой массива.Если у кого-то есть предложения, они приветствуются.

0 голосов
/ 11 декабря 2018

Я думаю, что вы можете попробовать сопоставление функций, например, SURF alogrithm, FLANN https://docs.opencv.org/3.3.0/dc/dc3/tutorial_py_matcher.html

http://www.coldvision.io/2016/06/27/object-detection-surf-knn-flann-opencv-3-x-cuda/

Пример обнаружения функции с использованием SURF: https://docs.opencv.org/3.0-beta/doc/tutorials/features2d/feature_detection/feature_detection.html

#include <stdio.h>
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;
using namespace cv::xfeatures2d;

void readme();

/** @function main */
int main( int argc, char** argv )
{
  if( argc != 3 )
  { readme(); return -1; }

  Mat img_1 = imread( argv[1], IMREAD_GRAYSCALE );
  Mat img_2 = imread( argv[2], IMREAD_GRAYSCALE );

  if( !img_1.data || !img_2.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 400;

  Ptr<SURF> detector = SURF::create( minHessian );

  std::vector<KeyPoint> keypoints_1, keypoints_2;

  detector->detect( img_1, keypoints_1 );
  detector->detect( img_2, keypoints_2 );

  //-- Draw keypoints
  Mat img_keypoints_1; Mat img_keypoints_2;

  drawKeypoints( img_1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
  drawKeypoints( img_2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT );

  //-- Show detected (drawn) keypoints
  imshow("Keypoints 1", img_keypoints_1 );
  imshow("Keypoints 2", img_keypoints_2 );

  waitKey(0);

  return 0;
  }

  /** @function readme */
  void readme()
  { std::cout << " Usage: ./SURF_detector <img1> <img2>" << std::endl; }
...