Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Block-matching Algorithm in OpenCV?

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!

Block-matching Algorithm in OpenCV?

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!

UPDATED: Template Matching function could help me in this situation?