Realizuję to zadanie następującym kodem (opis pod spodem):
- Kod: Zaznacz cały
void __fastcall TFotoEdytor::TBKorelacjaClick(TObject *Sender)
{
//ofstream wynik;
//wynik.open("wynik.txt");
//*******************************
//ofstream wyc;
//ofstream prob;
//wyc.open("wycinek.txt");
//prob.open("probka.txt");
Graphics::TBitmap *Wycinek = new Graphics::TBitmap();
Wycinek->PixelFormat = pf32bit;
int iterator = 0;
ShowMessage("Wczytaj wycinek");
if(OpenDialog2->Execute())
{
Wycinek->LoadFromFile(OpenDialog2->FileName);
int szerokosc = MainImage->Picture->Bitmap->Width;
int wysokosc = MainImage->Picture->Bitmap->Height;
caly = new int*[wysokosc];
int tmp;
for(int i=0; i<wysokosc; i++)
{
caly[i] = new int[szerokosc];
RGBQUAD *Linia = (RGBQUAD *) MainImage->Picture->Bitmap->ScanLine[i];
for (int j=0; j<szerokosc; j++, Linia++)
{
tmp = Linia->rgbRed;
tmp += Linia->rgbGreen;
tmp += Linia->rgbBlue;
tmp = tmp/3;
caly[i][j] = tmp;
}
}
//****************************
ShowMessage("caly w tablicy");
int *KorelacjaRGB,
rozmiar = (szerokosc - Wycinek->Width + 1)*(wysokosc - Wycinek->Height + 1);
KorelacjaRGB = new int[rozmiar];
//****************************
ShowMessage("tablica korelacji: " + IntToStr(rozmiar));
int rW, gW, bW;
int IloscWart = Wycinek->Width*Wycinek->Height;
int *WTabWartPix, *PTabWartPix;
WTabWartPix = new int[IloscWart]; //tablica wartosci pikseli wzorca
PTabWartPix = new int[IloscWart]; //tablica wartosci pikseli probki
//obliczenia dla wzorca
for (int i=0; i<Wycinek->Height; i++)
{
RGBQUAD *LiniaW = (RGBQUAD *) Wycinek->ScanLine[i];
for (int j=0; j<Wycinek->Width; j++, LiniaW++)
{
rW = LiniaW->rgbRed;
gW = LiniaW->rgbGreen;
bW = LiniaW->rgbBlue;
WTabWartPix[iterator] = (rW + gW + bW)/3;
//wyc << WTabWartPix[iterator] << endl;
iterator++;
}
}
//****************************
ShowMessage("wzorzec w tablicy: " + IntToStr(IloscWart));
ProgressBar1->Max = wysokosc - Wycinek->Height + 1;
iterator = 0;
float max1=0;
// obliczenia dla próbek
for (int i=0; i<wysokosc - Wycinek->Height + 1; i++)
{
ProgressBar1->StepIt();
for (int j=0; j<szerokosc - Wycinek->Width + 1; j++)
{
for (int k=0; k<Wycinek->Height; k++)
{
for (int l=0; l<Wycinek->Width; l++)
{
PTabWartPix[k*Wycinek->Width+l] = caly[i+k][j+l];
//prob << PTabWartPix[k*Wycinek->Width+l] << endl;
}
}
//Obliczenie korelacji próbki z wzorcem
KorelacjaRGB[iterator] = Korelacja(WTabWartPix, PTabWartPix, IloscWart);
//wynik << fixed << setprecision(2) << KorelacjaRGB[iterator] << endl;
if (max1<KorelacjaRGB[iterator])
max1 = KorelacjaRGB[iterator];
iterator++;
}
}
ShowMessage(max1);
iterator = 0;
//Znalezienie maksymalnej wartosci korelacji
int i_max = 0;
double max = KorelacjaRGB[0];
for (int i=1; i<rozmiar; i++)
if (KorelacjaRGB[i] > max)
{
max = KorelacjaRGB[i];
i_max = i;
}
//zaznaczenie wycinka o maksymalnej korelacji na obrazie
int l, t;
l = i_max / (szerokosc-Wycinek->Width+1);
t = i_max / (wysokosc-Wycinek->Height+1);
MainImage->Canvas->Brush->Style = bsClear;
MainImage->Canvas->Pen->Style = psDot;
MainImage->Canvas->Pen->Color = clRed;
MainImage->Canvas->Rectangle(l, t, l+Wycinek->Width, t+Wycinek->Height);
Label1->Caption = i_max;
Label2->Caption = KorelacjaRGB[i_max];
}
}
Cały obrazek, na którym wyszukuję fragmentu trafia do tablicy dwuwymiarowej 'caly'. Wzorzec trafia do jednowymiarowej tablicy WTabWartPix o odpowiednim rozmiarze, a porównywane próbki kolejno do tablicy PTabWartPix. Funkcja obliczająca wartość korelacji działa dobrze, bo na ręcznie utworzonych tablicach daje dobre wyniki, niemniej jednak kod wklejam poniżej.
Problem mam taki, że dla każdej próbki otrzymuję wartość korelacji 0. Męczę się z tym już drugi dzień i nie mogę wymyślić, co popsułem, dlatego proszę o pomoc.
Na koniec kod funkcji obliczającej korelację (jako parametry dostaje tablice wzorca i próbki oraz ich rozmiar):
- Kod: Zaznacz cały
double TFotoEdytor::Korelacja (int wzorzec[], int probka[], int size)
{
double SredniaP = 0, SredniaW = 0, SumaP = 0, SumaW = 0, KoreLicznik = 0,
KoreMianownik = 0, Spierw1 = 0, Spierw2 = 0;
for (int i=0; i<size; i++)
{
SumaW += wzorzec[i];
SumaP += probka[i];
}
SredniaW = SumaW/size;
SredniaP = SumaP/size;
for (int i=0; i<size; i++)
{
KoreLicznik += (wzorzec[i]-SredniaW)*(probka[i]-SredniaP);
Spierw1 += pow((wzorzec[i]-SredniaW),2);
Spierw2 += pow((probka[i]-SredniaP),2);
}
KoreMianownik = sqrt(Spierw1)*sqrt(Spierw2);
if (KoreMianownik == 0)
return 0;
else
return KoreLicznik/KoreMianownik;
}