Форум программистов, компьютерный форум, киберфорум
C++: OpenCV
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 30.06.2015
Сообщений: 9

Почему не так работает? Поиска фрагмента в полном изображении (OpenCV)

01.05.2018, 13:35. Показов 1441. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть такой алгоритм:

Пусть даны два изображения X и Y – изображение и образец, размеров (N1,N2) и (M1,M2) соответственно и Ni > Mi
Требуется найти координаты образца Y в полном изображении X и вычислить оценочную величину — меру близости.
  • Расширить изображение Y до размера (N1,N2), дополнив его нулями
  • Сформировать изображение E из единиц размера (M1,M2) и расширить до размера (N1,N2), дополнив его нулями
  • Вычислить <X,Y> = BFT ( FFT(X) * CONJUGATE ( FFT(Y) ) )
  • Вычислить <X,X> = BFT ( FFT(X) * CONJUGATE ( FFT(X) ) * CONJUGATE ( FFT(E) ) )
  • Вычислить M[i,j] = (f + <X,Y> [i,j])/(f + <X,X> [i,j])
  • В матрице M найти элемент с максимальным значением – координаты этого элемента и являются искомой позицией образца в полном изображении, а значение равно оценке меры сравнения.

FFT – операция прямого двухмерного дискретного преобразования Фурье
BFT – операция обратного двухмерного дискретного преобразования Фурье
CONJUGATE – операция вычисления матрицы из сопряжённых элементов

Я это попытался реализовать с помощью библиотеки OpenCV.Все равно выдает неправильные координаты.
Кто разбирается, прошу помощи.

И есть доп вопрос если кто поймет:
Я же правильно понимаю, что оригинал с начало нужно будет дополнить до размера квадратной матрицы и образец нужно будет дополнять до оригинала, потому что в алгоритме есть операция умножения матриц?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include "opencv2/opencv.hpp" 
#include <opencv2/highgui/highgui.hpp>
#include<iostream>
 
using namespace cv;
using namespace std;
 
typedef float fp;
typedef complex <fp> TCmplx;
typedef Mat_ <TCmplx> TComplexMat;
 
void DFT(Mat& A,Mat& B)
{
    Mat originalComplex[2] = { A, Mat::zeros(A.size(), CV_32F) };
    Mat dftReady;
    merge(originalComplex, 2, dftReady);
    Mat dftOfOriginal;
    dft(dftReady, dftOfOriginal, DFT_COMPLEX_OUTPUT);
    B = dftOfOriginal;
}
void showDFT(Mat& source)
{
    Mat splitArray[2] = { Mat::zeros(source.size(), CV_32F), Mat::zeros(source.size(), CV_32F) };
 
    split(source, splitArray);
 
    Mat dftMagnitude;
 
    magnitude(splitArray[0], splitArray[1], dftMagnitude);
 
    dftMagnitude += Scalar::all(1);
 
    log(dftMagnitude, dftMagnitude);
 
    normalize(dftMagnitude, dftMagnitude, 0, 1, CV_MINMAX);
 
    imshow("DFT", dftMagnitude);
    waitKey(0);
}
void invertDFT(Mat& source, Mat& destination)
{
    Mat inverse;
    dft(source, inverse, DFT_INVERSE | DFT_REAL_OUTPUT | DFT_SCALE);
    destination = inverse;
}
 
 
 
TComplexMat ConjugateMat(TComplexMat mat1)
{
    TComplexMat mat2 = mat1;
    if (mat1.size() != mat2.size())
        mat2 = TComplexMat(mat1.size());
    for (int i = 0; i < mat1.rows; i++)
    for (int j = 0; j < mat1.cols; j++)
    {
        mat2.at<TCmplx>(i, j).real(mat1.at<TCmplx>(i, j).real());
        mat2.at<TCmplx>(i, j).imag(-mat1.at<TCmplx>(i, j).imag());
    };
    return mat2;
};
 
 
 
Mat razmer(Mat H)
{
 
    if (H.rows > H.cols)
    {
        cout << H.rows<<endl;
        Mat B(H.rows, H.rows, 0);
        for (int i = 0; i < B.rows; i++)
        for (int j = 0; j < B.rows; j++)
        if (j >= H.cols)
            B.at<uchar>(i, j) = (uchar)0;
        else
            B.at<uchar>(i, j) = H.at<uchar>(i, j);
        return B;
    }
    else
    {
        cout << H.cols << endl;
        Mat B(H.cols, H.cols, 0);
        for (int i = 0; i < B.cols; i++)
        for (int j = 0; j < B.cols; j++)
        if (i >= H.rows)
        {
            B.at<uchar>(i, j) = (uchar)0;
            //cout << B.at<uchar>(i, j) << ' ' << endl;
            //cout << (uchar)0;
            //system("pause");
        }
        else
        {
            B.at<uchar>(i, j) = H.at<uchar>(i, j);
            //cout << H.at<uchar>(i, j) << ' ' << endl;
            //cout << (uchar)0;
            //system("pause");
        }
        return B;
    }
}
 
int main()
{
 
    // Load an image
    Mat H = imread("2.jpg", 0);
    Mat FirstImg = razmer(H);
    Mat Copy = FirstImg;
    Mat SecondImg = imread("eye.jpg", 0);
    imshow("firstImg", FirstImg);
    imshow("secondImg", SecondImg);
    Mat SecondImg2(FirstImg.rows, FirstImg.cols, 0);
    Mat E(FirstImg.rows, FirstImg.cols, 0);
 
 
    for (int i = 0; i < FirstImg.rows; i++)
    for (int j = 0; j < FirstImg.cols; j++)
        if ((i < SecondImg.rows) && (j < SecondImg.cols))
        {
            SecondImg2.at<uchar>(i, j) = SecondImg.at<uchar>(i, j);
            E.at<uchar>(i, j) = 1;
        }
        else
        {
            SecondImg2.at<uchar>(i, j) = (uchar)0;
            E.at<uchar>(i, j) = (uchar)0;
        }
 
    imshow("SecondImg2", SecondImg2);
 
 
 
    //1)
    Mat originalFloat1; 
    Mat originalFloat2;
    Mat originalFloat3;
    FirstImg.convertTo(originalFloat1, CV_32FC1, 1.0 / 255.0);
    SecondImg2.convertTo(originalFloat2, CV_32FC1, 1.0 / 255.0);
    Mat dftOfOriginal1;//FFT(X)
    Mat dftOfOriginal2;//FFT(Y)
    DFT(originalFloat1, dftOfOriginal1);
    DFT(originalFloat2, dftOfOriginal2);
    showDFT(dftOfOriginal1);
    showDFT(dftOfOriginal2);
    TComplexMat K = ConjugateMat(dftOfOriginal2), I; //CONJUGATE ( FFT(Y) )
    Mat A; //<X,Y>
    K = dftOfOriginal1*K;
    invertDFT(K, A);
    imshow("<X,Y>", A);
    waitKey();
 
    //2)
    E.convertTo(originalFloat3, CV_32FC1, 1.0 / 255.0);
    Mat dftOfOriginal3;//FFT(E)
    DFT(originalFloat3, dftOfOriginal3);
    K = ConjugateMat(dftOfOriginal1);//CONJUGATE ( FFT(X) )
    I = ConjugateMat(dftOfOriginal3);//CONJUGATE ( FFT(E) )
    K = dftOfOriginal1*K*I;
    Mat B; //<X,X>
    invertDFT(K, B);
    imshow("<X,X>", B);
    waitKey();
 
    //3)
    //uchar c = A.at<uchar>(0, 3) + 100 / B.at<uchar>(0, 3) + 100;
    
    Mat M(FirstImg.rows, FirstImg.cols, 0);
    for (int i = 0; i < M.rows; i++)
    for (int j = 0; j < M.cols; j++)
    {
        //cout << (int)A.at<uchar>(i, j) + 10 << '/' << (int)B.at<uchar>(i, j)+10 << endl;
        //if (B.at<uchar>(i, j) != NULL)
        M.at<uchar>(i, j) = (A.at<uchar>(i, j) + (uchar)100) / (B.at<uchar>(i, j) + (uchar)100);
        //else M.at<uchar>(i, j) = 0;
        
        //waitKey();
    }
 
    //4)
    int max = (int)M.at<uchar>(0, 0);
    int i_max = 0, j_max = 0;
    for (int i = 0; i <FirstImg.rows - SecondImg.rows; i++)
    for (int j = 0; j < FirstImg.cols - SecondImg.cols; j++)
    {
        //cout << (int)M.at<uchar>(i, j)<<' ';
        if ((int)M.at<uchar>(i, j)>max)
        {
 
            max = (int)M.at<uchar>(i, j);
            i_max = i;
            j_max = j;
        }
        //cout << endl;
    }
    cout << "i=" << i_max << " j=" << j_max << endl;
    //Rect r(i_max, j_max, SecondImg.cols, SecondImg.rows);
    Rect r(i_max, j_max, SecondImg.rows, SecondImg.cols);
    imshow("Res1", Copy);
    imshow("Res2", Copy(r));
    waitKey();
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.05.2018, 13:35
Ответы с готовыми решениями:

Поиск фрагмента в изображении
Т.к. не нашёл удовлетворяющего меня решения, сделал сам. Выкладываю, может кому пригодится. from PIL import Image def...

с++ Opencv 2.4 Определение лица на изображении
установил opencv2.4 http://www.samontab.com/web/2012/06/installing-opencv-2-4-1-ubuntu-12-04-lts/ Определение лица на изображении. ...

Как найти объект на изображении (openCV)?
Добрый день всем. возможно ли найти объект на изображение который находится ближе всего с помощью openCV. предварительно можно узнать...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.05.2018, 13:35
Помогаю со студенческими работами здесь

Почему так работает, а так нет?
так работает // Возведение b в степень s по модулю m float powmod(float b, long s) { float c=1; while (s) {

OpenCV поиск фрагмента картинки по шаблону (template)
Здравствуйте! такой вопрос: создал прилагу по поиску фрагмента на картинке по шаблону #define CV_TM_SQDIFF 0 ...

Глобальные и локальные переменные, одна и та же прога в процедуре Не работает, а просто так работает. Почему?
Здравствуйте, есть программка которая переводит из 2-ной системы в 10-ную. Она работает. А вот поместил я её в процедуру и работать...

Почему так работает?
Связал данные с сайта и поставил таймер на проверку. Вот почему так работает? Когда на сайте в #knb_count_my_rows стоит 0, он...

Почему так не работает
День добрый. Получаю значение с формы от пользователя и вывожу его. Интересует почему не работает так: $_POST = $a; echo $a; Не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru