Untitled

mail@pastecode.io avatar
unknown
c_cpp
4 months ago
3.7 kB
1
Indexable
#include <iostream>
#include <vector>
#include <limits>
#include <stdint.h>

// MSE 
double calculateMSE(const std::vector<std::vector<int32_t>>& block1, const std::vector<std::vector<int32_t>>& block2) {
    double mse = 0.0;
    int32_t rows = block1.size();
    int32_t cols = block1[0].size();
    
    for (int32_t i = 0; i < rows; ++i) {
        for (int32_t j = 0; j < cols; ++j) {
            mse += (block1[i][j] - block2[i][j]) * (block1[i][j] - block2[i][j]);
        }
    }
    
    return mse / (rows * cols);
}

// Lấy block từ frame
std::vector<std::vector<int32_t>> getBlock(const std::vector<std::vector<int32_t>>& frame, int32_t x, int32_t y, int32_t blockSize) {
    std::vector<std::vector<int32_t>> block(blockSize, std::vector<int32_t>(blockSize));
    
    for (int32_t i = 0; i < blockSize; ++i) {
        for (int32_t j = 0; j < blockSize; ++j) {
            block[i][j] = frame[x + i][y + j];
        }
    }
    
    return block;
}

// Tìm vector chuyển động sử dụng FS
std::pair<int32_t, int32_t> findMotionVector(const std::vector<std::vector<int32_t>>& refFrame, 
                                     const std::vector<std::vector<int32_t>>& targetFrame, 
                                     int32_t startX, int32_t startY, int32_t blockSize, int32_t searchRange) {
    std::pair<int32_t, int32_t> bestMatch(0, 0);
    double minMSE = std::numeric_limits<double>::max();
    
    std::vector<std::vector<int32_t>> referenceBlock = getBlock(refFrame, startX, startY, blockSize);
    
    for (int32_t i = -searchRange; i <= searchRange; ++i) {
        for (int32_t j = -searchRange; j <= searchRange; ++j) {
            int32_t targetX = startX + i;
            int32_t targetY = startY + j;
            
            // avoid tránh block out of range khỏi frame
            if (targetX >= 0 && targetX + blockSize <= targetFrame.size() &&
                targetY >= 0 && targetY + blockSize <= targetFrame[0].size()) {
                
                std::vector<std::vector<int32_t>> targetBlock = getBlock(targetFrame, targetX, targetY, blockSize);
                double mse = calculateMSE(referenceBlock, targetBlock);
                
                if (mse < minMSE) {
                    minMSE = mse;
                    bestMatch = {i, j};
                }
            }
        }
    }
    
    return bestMatch;
}

int32_t main() {
    // frame mẫu
    std::vector<std::vector<int32_t>> refFrame = {
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 5, 5, 5, 40, 40, 40, 40},
        {40, 5, 5, 5, 40, 40, 40, 40},
        {40, 5, 5, 5, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40}
    };
    
    std::vector<std::vector<int32_t>> targetFrame = {
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40},
        {5, 5, 5, 40, 40, 40, 40, 40},
        {5, 5, 5, 40, 40, 40, 40, 40},
        {5, 5, 5, 40, 40, 40, 40, 40},
        {40, 40, 40, 40, 40, 40, 40, 40}
    };
    
    int32_t blockSize = 4; // N = 4
    int32_t searchRange = 4;
    int32_t startX = 1; 
    int32_t startY = 1; 
    
    std::pair<int32_t, int32_t> motionVector = findMotionVector(refFrame, targetFrame, startX, startY, blockSize, searchRange);
    
    std::cout << "Motion Vector: (" << motionVector.first << ", " << motionVector.second << ")" << std::endl;
    
    return 0;
}
Leave a Comment