Hi everyone, I have a question if its possible to find a Block Matching Compensation Algorithm in OpenCV, or if exits a more easy method to implement it.
I tried to implement it, witout success.
#include "opencv2/opencv.hpp"
#include <iostream>
#include <stdio.h>
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
using namespace cv;
using namespace std;
typedef Point_<int> Point2i;
int main()
{
Mat prueba, Ycrcb, I1,I2;
std::vector<cv::Mat> lum1;
std::vector<cv::Mat> lum2;
Mat lumI1,lumI2;
int blocksize = 16;
std::vector<cv::Mat> blocks[blocksize*blocksize];
Mat A = imread("/home/eduardo/Documents/PROJECT DIP/project/A.jpg");
Mat B = imread("/home/eduardo/Documents/PROJECT DIP/project/B.jpg");
int rows = A.rows;
int cols = A.cols;
cout << "rows = " << rows << endl;
cout << "cols = " << cols << endl;
cvtColor(A, A, CV_BGR2YCrCb);
cvtColor(B, B, CV_BGR2YCrCb);
split(A,lum1);
split(B,lum2);
lumI1 = lum1[0];
lumI2 = lum2[0];
//method to cut the images <---- IMPORTANT!
cv::Size macroblock(blocksize,blocksize);
std::vector<Mat> smallImages;
for (int y = 0; y < rows; y += macroblock.height)
{
for (int x = 0; x < cols; x += macroblock.width)
{
cv::Rect rect = cv::Rect(x,y, macroblock.width, macroblock.height);
smallImages.push_back(cv::Mat(lumI2, rect));
}
}
//arr[ 0*cols +0 ] = .... Para el futuro.
int bRows = rows/blocksize;
int bCols = cols/blocksize;
int x =bRows; int y = bCols;
cout << "bRows = " << bRows << endl;
cout << "bCols = " << bCols << endl;
int position = (x-1)*bCols + (y-1);
cout << "position = " << position << endl;
Everything ok until here, But when i try to implement the algorithm, the result are not good. In big words, Im using Rect() to evaluate one block with another in a range of [-search:search] and when i found the minimun error, I stored at a matrix x and y. Then, I plan to fullfill the blocks into a big image, but my result of X and Y doesnt make sense.
Mat block,B2;
int TE;
int E = 255*pow(blocksize,2);
Mat Err = Mat::zeros(bRows, bCols, CV_8U);
Mat xp = Mat::zeros(bRows, bCols, CV_8U);
Mat yp = Mat::zeros(bRows, bCols, CV_8U);
for (int r =1; r<=bRows;r++)
{
//cout <<"begining = " << varE << endl;
for (int c =1; c<=bCols;c++)
{
int rb=r*blocksize;
int cb=c*blocksize;
int search=blocksize*1.5;
for(int dr = -search; dr<=search;dr++)
{
for(int dc = -search; dc<=search;dc++)
{
if(rb+dr-blocksize>0 && rb+dr<=rows && cb+dc-blocksize>0 && cb+dc<=cols)
{
int x1 = cb+dc-blocksize;
int y1 = rb+dr-blocksize;
block = lumI1( Rect(x1, y1,16,16) );
position = (r-1)*bCols + (c-1);
B2 = smallImages[position];
TE= sum(cv::abs(block - B2))[0];
if(TE<E)
{
Err.at<int>(r,c) = TE; //store the error
xp.at<int>(r,c) = x1;
yp.at<int>(r,c) = y1;
E=TE;
}
}
}
}
E = 255*pow(blocksize,2);
}
}
I will appreciate any help. The algorithm runs but the results are not good. Thank you!