Exemplo n.º 1
0
CvPoint2D64f SimilarityTransform::applyToPoint(CvPoint2D64f p) const
{
    AffineTransform * pAT = getAffineTransform();
    CvPoint2D64f transPoint = pAT->applyToPoint(p);
    delete pAT;
    return transPoint;
}
Exemplo n.º 2
0
vector<Point2f> UIGridDetector::generateGrid(vector<Point2f> corners,
                                             unsigned int cols, unsigned int rows) const {
    if (corners.size() != 3){
        std::stringstream stream;
        stream << "UIGridDetector::generateGrid - generating from " << corners.size() << " corners is not supported";
        throw std::runtime_error(stream.str());
    }

    unsigned int _cols = (cols-1),
                 _rows = (rows-1),
                 gridSize =  cols * rows;

    // Compute affine transformation between image and fictive grid
    vector<Point2f> gridCorners {{Point2f(0.f, 0.f), Point2f(1.f, 0.f), Point2f(0.f, 1.f)}};
    Mat warpMat = getAffineTransform(gridCorners, corners);

    // Generate fictive grid
    vector<Point2f> grid(gridSize);
    float dCol = 1.f / _cols,
          dRow = 1.f / _rows;

    for (unsigned int iRow = 0; iRow < rows; iRow++)
        for (unsigned int iCol = 0; iCol < cols; iCol++)
            grid[iRow * cols + iCol] = Point2f(iCol * dCol, iRow * dRow);

    // Transform it to image coordinates
    vector<Point2f> result(gridSize);
    transform(grid, result, warpMat);
    return result;
}
Exemplo n.º 3
0
vector<Mat> getAllAffineTransforms(const vector<vector<Point2f> > srcTriangles, const vector<vector<Point2f> > dstTriangles)
{
    vector<Mat> curSetAffines;
    for (int i = 0; i < srcTriangles.size(); i++)
    {
        Point2f vf0 = srcTriangles[i][0];
        Point2f vf1 = srcTriangles[i][1];
        Point2f vf2 = srcTriangles[i][2];
        Point2f src[3] = {vf0, vf1, vf2};
        Point2f vt0 = dstTriangles[i][0];
        Point2f vt1 = dstTriangles[i][1];
        Point2f vt2 = dstTriangles[i][2];
        Point2f dst[3] = {vt0, vt1, vt2};
        Mat Affine = getAffineTransform(src, dst);
        /*
        // last row of Affine mat: [0 0 1]
        double* lastAffineMatRow = (double*)Affine.data;
        
        for (int k = 0; k < 6; k++)
        {
            if (lastAffineMatRow[k] < 0.0001 && lastAffineMatRow[k] > -0.0001)
                lastAffineMatRow[k] = 0.;
            if (lastAffineMatRow[k] < 1.0001 && lastAffineMatRow[k] > .9999)
                lastAffineMatRow[k] = 1.;
        }*/

        curSetAffines.push_back(Affine);//getAffineTransform(src, dst));
    }
    
    return curSetAffines;
}
Exemplo n.º 4
0
bool FacemarkKazemiImpl::convertToUnit(Rect r,Mat &warp){
    Point2f srcTri[3],dstTri[3];
    dstTri[0]=Point2f(0,0);
    dstTri[1]=Point2f(1,0);
    dstTri[2]=Point2f(0,1);
    srcTri[0]=Point2f((float)r.x,(float)r.y);
    srcTri[1]=Point2f((float)r.x+r.width,(float)r.y);
    srcTri[2]=Point2f((float)r.x,(float)r.y+(float)1.3*r.height);
    warp=getAffineTransform(srcTri,dstTri);
    return true;
}
Exemplo n.º 5
0
SimilarityTransform * SimilarityTransform::accumulate(const Transform * T2) const
{
    AffineTransform * T1aff = getAffineTransform();
    AffineTransform * T2aff = dynamic_cast<const SimilarityTransform *>(T2)->getAffineTransform();
    AffineTransform * aff = dynamic_cast<AffineTransform *>(T1aff->accumulate(T2aff));

    SimilarityTransform * pSim = aff->getSimilarityTransform();
    
    delete T1aff;
    delete T2aff;
    delete aff;

    return pSim;
}
Exemplo n.º 6
0
SimilarityTransform * SimilarityTransform::accumulateInverse(const Transform * T2) const
{
    AffineTransform * T1aff = getAffineTransform();
    AffineTransform * T2aff = dynamic_cast<const SimilarityTransform *>(T2)->getAffineTransform();
    AffineTransform * aff = T1aff->accumulateInverse(T2aff);
    SimilarityTransform * pSim = aff->getSimilarityTransform();
//    m->scale_ = scale_ * T2sim->scale_;
//    m->translation_ = translation_ + T2sim->translation_; //Do we need to scale here?? No
    
    delete T1aff;
    delete T2aff;
    delete aff;

    return pSim;
}
Exemplo n.º 7
0
void OpenCV_Function::warpAffine()  {  
	 //【1】参数准备  
    //定义两组点,代表两个三角形  
    cv::Point2f srcTriangle[3];  
    cv::Point2f dstTriangle[3];  
    //定义一些Mat变量  
    cv::Mat rotMat( 2, 3, CV_32FC1 );  
    cv::Mat warpMat( 2, 3, CV_32FC1 );  

    //【2】加载源图像并作一些初始化  
    g_srcImage=cv::imread("girl-t1.jpg");
    // 设置目标图像的大小和类型与源图像一致  
    g_resultImage = cv::Mat::zeros( g_srcImage.rows, g_srcImage.cols, g_srcImage.type() );  
  
    //【3】设置源图像和目标图像上的三组点以计算仿射变换  
    srcTriangle[0] = cv::Point2f( 0,0 );  
    srcTriangle[1] = cv::Point2f( static_cast<float>(g_srcImage.cols - 1), 0 );  
    srcTriangle[2] = cv::Point2f( 0, static_cast<float>(g_srcImage.rows - 1 ));  
  
    dstTriangle[0] = cv::Point2f( static_cast<float>(g_srcImage.cols*0.0), static_cast<float>(g_srcImage.rows*0.33));  
    dstTriangle[1] = cv::Point2f( static_cast<float>(g_srcImage.cols*0.65), static_cast<float>(g_srcImage.rows*0.35));  
    dstTriangle[2] = cv::Point2f( static_cast<float>(g_srcImage.cols*0.15), static_cast<float>(g_srcImage.rows*0.6));  
  
    //【4】求得仿射变换  
    warpMat = getAffineTransform( srcTriangle, dstTriangle );  
    //【5】对源图像应用刚刚求得的仿射变换  
   cv::warpAffine( g_srcImage, g_resultImage, warpMat, g_resultImage.size() );  
  
    //【6】对图像进行缩放后再旋转  
    cv::Point center = cv::Point( g_srcImage.cols/2, g_srcImage.rows/2 );  
    double angle = -20.0;  
    double scale = 1;  
    // 通过上面的旋转细节信息求得旋转矩阵  
    rotMat =cv::getRotationMatrix2D( center, angle, scale );  
    // 旋转已缩放后的图像  
    cv::warpAffine( g_resultImage, g_templateImage, rotMat, g_resultImage.size() );  
	cv::imshow("【原始图】",g_srcImage);  
	cv::imshow( "g_templateImage", g_templateImage );
    cv::imshow( "g_resultImage", g_resultImage );  
}  
Exemplo n.º 8
0
void SimilarityTransform::applyToPoints(const CvMat * positions, CvMat * newPositions) const
{
    AffineTransform * pAT = getAffineTransform();
    pAT->applyToPoints(positions, newPositions);
    delete pAT;
}
Exemplo n.º 9
0
void SimilarityTransform::applyToImage(const IplImage * sourceIm, IplImage * destIm) const
{
    AffineTransform * pAT = getAffineTransform();
    pAT->applyToImage(sourceIm, destIm);
    delete pAT;
}
Exemplo n.º 10
0
Mat AAM::findTransformationMatrix(Point2f from[3], Point2f to[3])
{
    Mat warp_mat( 2, 3, CV_32FC1 );
    warp_mat = getAffineTransform( from, to );
    return warp_mat;
}
Exemplo n.º 11
0
//Processes a frame and returns output image
bool HiLight::processFrame(const cv::Mat& inputFrame, int* screen_position, double current_timestamp, char *results, bool* denoise_check, bool* first_bit_check, int* hilight_line_index, char* hilight_results_tmp )
{
    *denoise_check = false;
    *first_bit_check = false;
    if(!initialized){
        initialized = true;
        for(int i = 0; i<grid_x; i++){
            for(int j = 0; j<grid_y; j++ ){
                for (int k = 0; k < first_bit_window; k++){
                    first_bit_color_window[i][j][k] = 0;
                }
                for (int k = 0; k < N; k++){
                    grid_color_intensity[i][j][k] = 0;
                    hilight_results_stack[i][j][k] = 0;
                }
                hilight_results[i][j] = 0;
            }
        }
        if (isImage){
            MVDR = true;
            first_2_ratio = 0.6;//0.8
            first_bit_voting = 0.5;//0.7
        }else{
            MVDR = false;
            first_2_ratio = 0.8; //0.7
            first_bit_voting = 0.7; //0.6
        }
        window_index = 0;
        first_bit_detected = false;
        first_bit_index = 0;
        hilight_stack_index = 0;
        start_time = current_timestamp;
        current_time = current_timestamp;
        denoise_start = false;
        MVDR_index = 0;
        bit_counter = 0;
        results_stack_counter = 0;
        fftSetup = vDSP_create_fftsetup(LOG_N, kFFTRadix2);
        start_receiving = false;
        counter_after_detect_1= 0;
        
        first_bit_1_detected = false;
        first_bit_2_detected = false;
        hilight_first_bit_index = 0;
        hilight_first_bit_counter = 0;
        hilight_first_bit_position = 0;
        
        if (screen_position[2] < screen_position[4]){
            image_ROI_position[0].y = screen_position[2];
        }else{
            image_ROI_position[0].y = screen_position[4];
        }
        
        if (screen_position[1] < screen_position[7]){
            image_ROI_position[0].x = screen_position[1];
        }else{
            image_ROI_position[0].x = screen_position[7];
        }
        
        if (screen_position[6] < screen_position[8]){
            image_ROI_position[1].y = screen_position[8];
        }else{
            image_ROI_position[1].y = screen_position[6];
        }
        
        if (screen_position[5] < screen_position[3]){
            image_ROI_position[1].x = screen_position[3];
        }else{
            image_ROI_position[1].x = screen_position[5];
        }
        
        if (isImage){
            // Set grids points to calculate the grid position
            for (int i = 0; i <= grid_x * grid_x_MVDR; i++){
                grids_points_top_image[i].x = screen_position[1] + (screen_position[3] - screen_position[1]) / grid_x / grid_x_MVDR * i;
                grids_points_top_image[i].y = screen_position[2] + (screen_position[4] - screen_position[2]) / grid_x / grid_x_MVDR * i;
                grids_points_bottom_image[i].x = screen_position[7] + (screen_position[5] - screen_position[7]) / grid_x / grid_x_MVDR * i;
                grids_points_bottom_image[i].y = screen_position[8] + (screen_position[6] - screen_position[8]) / grid_x / grid_x_MVDR * i;
            }
            
            for (int i = 0; i <= grid_y * grid_y_MVDR; i++){
                grids_points_left_image[i].x = screen_position[1] + (screen_position[7] - screen_position[1]) / grid_y / grid_y_MVDR * i;
                grids_points_left_image[i].y = screen_position[2] + (screen_position[8] - screen_position[2]) / grid_y / grid_y_MVDR * i;
                grids_points_right_image[i].x = screen_position[3] + (screen_position[5] - screen_position[3]) / grid_y / grid_y_MVDR * i;
                grids_points_right_image[i].y = screen_position[4] + (screen_position[6] - screen_position[4]) / grid_y / grid_y_MVDR * i;
            }
            
            for (int i = 0; i < grid_x * grid_x_MVDR; i++){
                for (int j = 0; j < grid_y * grid_y_MVDR; j++){
                    cv::Point2f r1;
                    cv::Point2f r2;
                    cv::Point2f r3;
                    cv::Point2f r4;
                    intersection(grids_points_top_image[i], grids_points_bottom_image[i], grids_points_left_image[j], grids_points_right_image[j], r1);//top left
                    intersection(grids_points_top_image[i+1], grids_points_bottom_image[i+1], grids_points_left_image[j], grids_points_right_image[j], r2);//top right
                    intersection(grids_points_top_image[i+1], grids_points_bottom_image[i+1], grids_points_left_image[j+1], grids_points_right_image[j+1], r3);// bottom right
                    intersection(grids_points_top_image[i], grids_points_bottom_image[i], grids_points_left_image[j+1], grids_points_right_image[j+1], r4);//bottom left
                    
                    //refine grid_position
                    if (r1.x <= r4.x){
                        grids_position_image[i][j][0].x = r4.x - image_ROI_position[0].x;
                    }else{
                        grids_position_image[i][j][0].x = r1.x - image_ROI_position[0].x;
                    }
                    
                    if (r1.y <= r2.y){
                        grids_position_image[i][j][0].y = r2.y - image_ROI_position[0].y;
                    }else{
                        grids_position_image[i][j][0].y = r1.y - image_ROI_position[0].y;
                    }
                    
                    if (r3.x <= r2.x){
                        grids_position_image[i][j][1].x = r3.x - image_ROI_position[0].x;
                    }else{
                        grids_position_image[i][j][1].x = r2.x - image_ROI_position[0].x;
                    }
                    
                    if (r3.y <= r4.y){
                        grids_position_image[i][j][1].y = r3.y - image_ROI_position[0].y;
                    }else{
                        grids_position_image[i][j][1].y = r4.y - image_ROI_position[0].y;
                    }
                }
            }
        }else{
            // Set grids points to calculate the grid position
            for (int i = 0; i <= grid_x; i++){
                grids_points_top_video[i].x = screen_position[1] + (screen_position[3] - screen_position[1]) / grid_x * i;
                grids_points_top_video[i].y = screen_position[2] + (screen_position[4] - screen_position[2]) / grid_x * i;
                grids_points_bottom_video[i].x = screen_position[7] + (screen_position[5] - screen_position[7]) / grid_x * i;
                grids_points_bottom_video[i].y = screen_position[8] + (screen_position[6] - screen_position[8]) / grid_x * i;
            }
            
            for (int i = 0; i <= grid_y; i++){
                grids_points_left_video[i].x = screen_position[1] + (screen_position[7] - screen_position[1]) / grid_y * i;
                grids_points_left_video[i].y = screen_position[2] + (screen_position[8] - screen_position[2]) / grid_y * i;
                grids_points_right_video[i].x = screen_position[3] + (screen_position[5] - screen_position[3]) / grid_y * i;
                grids_points_right_video[i].y = screen_position[4] + (screen_position[6] - screen_position[4]) / grid_y * i;
            }
            
            for (int i = 0; i < grid_x; i++){
                for (int j = 0; j < grid_y; j++){
                    cv::Point2f r1;
                    cv::Point2f r2;
                    cv::Point2f r3;
                    cv::Point2f r4;
                    intersection(grids_points_top_video[i], grids_points_bottom_video[i], grids_points_left_video[j], grids_points_right_video[j], r1);//top left
                    intersection(grids_points_top_video[i+1], grids_points_bottom_video[i+1], grids_points_left_video[j], grids_points_right_video[j], r2);//top right
                    intersection(grids_points_top_video[i+1], grids_points_bottom_video[i+1], grids_points_left_video[j+1], grids_points_right_video[j+1], r3);// bottom right
                    intersection(grids_points_top_video[i], grids_points_bottom_video[i], grids_points_left_video[j+1], grids_points_right_video[j+1], r4);//bottom left
                    
                    //refine grid_position
                    if (r1.x <= r4.x){
                        grids_position_video[i][j][0].x = r4.x - image_ROI_position[0].x;
                    }else{
                        grids_position_video[i][j][0].x = r1.x - image_ROI_position[0].x;
                    }
                    
                    if (r1.y <= r2.y){
                        grids_position_video[i][j][0].y = r2.y - image_ROI_position[0].y;
                    }else{
                        grids_position_video[i][j][0].y = r1.y - image_ROI_position[0].y;
                    }
                    
                    if (r3.x <= r2.x){
                        grids_position_video[i][j][1].x = r3.x - image_ROI_position[0].x;
                    }else{
                        grids_position_video[i][j][1].x = r2.x - image_ROI_position[0].x;
                    }
                    
                    if (r3.y <= r4.y){
                        grids_position_video[i][j][1].y = r3.y - image_ROI_position[0].y;
                    }else{
                        grids_position_video[i][j][1].y = r4.y - image_ROI_position[0].y;
                    }
                }
            }
        }
        
        srcTri[0] = cv::Point2f( screen_position[2],screen_position[1] );
        srcTri[1] = cv::Point2f( screen_position[4],screen_position[3] );
        srcTri[2] = cv::Point2f( screen_position[6],screen_position[5] );
        
        dist_top = sqrt(pow(screen_position[4]-screen_position[2],2.0) + pow(screen_position[3]-screen_position[1],2.0));
        dstTri[0] = cv::Point2f( screen_position[2],screen_position[1] );
        dstTri[1] = cv::Point2f( screen_position[2],screen_position[1] + dist_top );
        dstTri[2] = cv::Point2f( screen_position[2] + (int)(dist_top*transmitter_screen_ratio),screen_position[1] + dist_top);
        warp_mat = getAffineTransform( srcTri, dstTri );
    }else{
        current_time = current_timestamp;
    }
    
    //crop the transmitter screen from the captured image
    cv::Mat image_ROI = inputFrame(cv::Range(image_ROI_position[0].y, image_ROI_position[1].y), cv::Range(image_ROI_position[0].x, image_ROI_position[1].x));
    getGray_HiLight(image_ROI, grayImage);
    image_ROI.release();
    
    for (int c = 0; c < grid_x; c++){
        for (int r = 0; r < grid_y; r++){
            brightness[c][r] = 0;
        }
    }
    if (isImage){
        int brightness_c = 0;
        int brightness_r = 0;
        for (int c = 0; c < grid_x * grid_x_MVDR; c++){
            for (int r = 0; r < grid_y * grid_y_MVDR; r++)
            {
                cv::Mat tile = grayImage(cv::Range(grids_position_image[c][r][0].y + grid_margin, grids_position_image[c][r][1].y - grid_margin)
                                         , cv::Range(grids_position_image[c][r][0].x + grid_margin, grids_position_image[c][r][1].x - grid_margin));
                
                cv::Scalar pixel_scalar = cv::mean(tile);
                tile.release();
                float brightness_tmp =pixel_scalar[0];
                
                if (MVDR){
                    if(!denoise_start && MVDR_index < MVDR_frame){
                        grid_color_intensity_MVDR[c][r][MVDR_index] = brightness_tmp;
                        if ( c == grid_x * grid_x_MVDR -1 && r == grid_y * grid_y_MVDR - 1){
                            MVDR_index++;
                        }
                    }else if(!denoise_start && MVDR_index >= MVDR_frame){
                        denoise_start = true;
                        *denoise_check = true;
                        get_MVDR_weighting(grid_color_intensity_MVDR, MVDR_weighting);
                        
                        //print MVDR matrix
                        if (isDebug){
                            for (int i = 0; i < grid_x * grid_x_MVDR; i++){
                                for (int j = 0; j < grid_y * grid_y_MVDR; j++){
                                    printf("%f\t", MVDR_weighting[i][j]);
                                }
                                printf("\n");
                            }
                        }
                    }else{
                        brightness_c = floor(c*1.0/grid_x_MVDR);
                        brightness_r = floor(r*1.0/grid_y_MVDR);
                        brightness[brightness_c][brightness_r] = brightness[brightness_c][brightness_r] + brightness_tmp * MVDR_weighting[c][r];
                    }
                }else{
                    brightness_c = floor(c*1.0/grid_x_MVDR);
                    brightness_r = floor(r*1.0/grid_y_MVDR);
                    brightness[brightness_c][brightness_r] = brightness[brightness_c][brightness_r] + brightness_tmp;
                }
            }
        }
    }else{
        for (int c = 0; c < grid_x; c++){
            for (int r = 0; r < grid_y; r++)
            {
                cv::Mat tile = grayImage(cv::Range(grids_position_video[c][r][0].y + grid_margin, grids_position_video[c][r][1].y - grid_margin)
                                         , cv::Range(grids_position_video[c][r][0].x + grid_margin, grids_position_video[c][r][1].x - grid_margin));
                
                cv::Scalar pixel_scalar = cv::mean(tile);
                tile.release();
                float brightness_tmp =pixel_scalar[0];
                brightness[c][r] = brightness_tmp;
            }
        }
    }

    if (denoise_start || !MVDR){
        for (int c = 0; c < grid_x; c++){
            for (int r = 0; r < grid_y; r++){
                if (window_index<(N-1)) {
                    grid_color_intensity[c][r][window_index] = brightness[c][r];
                    window_index++;
                }else{
                    int i;
                    float fft_sum_N_over_2 = 0;
                    for (i = 1; i < N; i++){
                        grid_color_intensity[c][r][i-1] = grid_color_intensity[c][r][i];
                    }
                    grid_color_intensity[c][r][N-1] = brightness[c][r];
                    
                    for (i = 0; i < N/2; i++){
                        fft_sum_N_over_2 = fft_sum_N_over_2 + grid_color_intensity[c][r][2*i] - grid_color_intensity[c][r][2*i+1];
                    }

                    // Initialize the input buffer with a sinusoid
                    
                    // We need complex buffers in two different formats!
                    tempSplitComplex.realp = new float[N/2];
                    tempSplitComplex.imagp = new float[N/2];
                    
                    // ----------------------------------------------------------------
                    // Forward FFT
                    
                    // Scramble-pack the real data into complex buffer in just the way that's
                    // required by the real-to-complex FFT function that follows.
                    vDSP_ctoz((DSPComplex*)grid_color_intensity[c][r], 2, &tempSplitComplex, 1, N/2);
                    
                    // Do real->complex forward FFT
                    vDSP_fft_zrip(fftSetup, &tempSplitComplex, 1, LOG_N, kFFTDirection_Forward);
                    
                    int max_pulse_index = object_pulse_threashold;
                    float max_pulse = -100;
                    float object_pulse_power_1 = LinearToDecibel(pow (fft_sum_N_over_2, 2.0)/ N);
                    float object_pulse_power_2;
                    int object_pulse_force;
                    int object_pulse;
                    for (int k = object_pulse_threashold; k < N/2; k++)
                    {
                        float spectrum = LinearToDecibel((pow (tempSplitComplex.realp[k], 2.0) + pow (tempSplitComplex.imagp[k], 2.0))/ 4/ N);
                        if (max_pulse<spectrum){
                            max_pulse = spectrum;
                            max_pulse_index = k;
                        }
                        if(k == object_pulse_2){
                            object_pulse_power_2 = spectrum;
                        }
                    }
                    
                    delete tempSplitComplex.realp;
                    delete tempSplitComplex.imagp;
                    
                    if(max_pulse < object_pulse_power_1 && object_pulse_power_1 > -25){
                        object_pulse = 1;
                    }else if(max_pulse == object_pulse_power_2){
                        object_pulse = 2;
                    }else{
                        object_pulse = 0;
                    }
                    
                    if(object_pulse_power_1 >= object_pulse_power_2){
                        object_pulse_force = 1;
                    }else{
                        object_pulse_force = 2;
                    }
                    
                    //decode data by find the peak frequency power
                    if (first_bit_detected){
                        if (first_bit_1_detected && isCalibrate){
                            hilight_first_bit_stack[c][r][hilight_first_bit_index] = object_pulse_force;
                        }
                        if(current_time - start_time >= N / 60.0 * (bit_counter + 1)){
                            hilight_results[c][r] = get_hilight_results(hilight_results_stack[c][r], hilight_stack_index);
                            hilight_results_stack[c][r][0] = object_pulse_force;
                        }else{
                            hilight_results_stack[c][r][hilight_stack_index] = object_pulse_force;
                        }
                    }else{
                        first_bit_color_window[c][r][first_bit_index] = object_pulse;
                    }
                }
            }
        }

        if (first_bit_1_detected && isCalibrate){
            hilight_first_bit_timestamp[hilight_first_bit_index++] = current_time;
        }if(first_bit_2_detected && isCalibrate){
            first_bit_2_detected = false;
            hilight_first_bit_counter++;
            if (hilight_first_bit_counter == N/2){
                calibrate_first_bit_position();
            }
        }
        if (first_bit_detected){
            if(current_time - start_time >= N / 60.0 * (bit_counter + 1)){
                int counter_for_2 = 0;
                for (int i = 0; i < grid_x; i++){
                    for (int j = 0; j <  grid_y; j++){
                        if (isDebug || start_receiving){
                            printf("%d ",hilight_results[i][j]);
                        }
                        if (hilight_results[i][j] == 2){
                            counter_for_2++;
                        }
                    }
                }
                if (isDebug || start_receiving){
                    printf("\n");
                }
                hilight_stack_index = 1;
                bit_counter++;
                
                if (!start_receiving){
                    counter_after_detect_1++;
                    if (counter_after_detect_1 > 3){
                        reset();
                    }else{
                        if(counter_for_2 >= (double)grid_x * grid_y * first_2_ratio){
                            first_bit_2_detected = true;
                            start_receiving = true;
                            *first_bit_check = true;
                            if (isDebug){
                                printf("\n");
                            }
                        }
                    }
                    return false;
                }else{
                    int results_counter_tmp =0;
                    for (int i = 0; i < grid_x; i++){
                        for (int j = 0; j <  grid_y; j++){
                            output_bit_stack[results_stack_counter++] = hilight_results[i][j];
                            hilight_results_tmp[results_counter_tmp++] = hilight_results[i][j] + '0' - 1;
                        }
                    }
                    hilight_line_index[0] = results_stack_counter/grid_x/grid_y;
                    
                    if (results_stack_counter == output_bit_stck_length){
                        results_stack_counter = 0;
                        get_char_from_bits(output_bit_stack, results);
                        
                        printf("%s\n",results);
                        
                        if (demo){
                            debug_reset();
                            return true;
                        }else{
                            debug_reset();
                            return false;
                        }
                    }else{
                        return false;
                    }
                }
            }else{
                hilight_stack_index++;
            }
        }else{
            if(first_bit_index<first_bit_window-1){
                first_bit_index++;
            }else{
                first_bit_detected = detect_first_bit(first_bit_color_window);
                if (first_bit_detected){
                    if (isCalibrate){
                        first_bit_1_detected = true;
                    }
                    start_time = current_time;
                }
            }
        }
    }
    return false;
}
void *affine_loop(void *number)
{

/*
	if(set_single_core_affinity()!=EXIT_SUCCESS)
	{
		perror("Core Affinity");
	}
*/

	int block_size;
	int max_files;
	int i=0;
	int section=0;
	float pos[8]={0,0,1,0,0,1,1,1};

	Point2f srcTri[4];
	Point2f dstTri[4];

	max_files=3601;
	block_size=max_files/4;

	Mat rot_mat( 2, 3, CV_32FC1 );
	Mat warp_mat( 2, 3, CV_32FC1 );


	// Output variables
	Mat src, warp_dst, warp_rotate_dst;

	struct thread_limits *ptr_obj = (struct thread_limits *) number;
	int start_loop = ptr_obj->start_no;
	int stop_loop  = ptr_obj->stop_no;

	/*------------------------- Starting the loop --------------------------*/

	for (i=start_loop; i<=stop_loop; i++)
	{

		/*------------------------- Loading the Image --------------------------*/

		if(option==1)
		{
			// Select the right frame
			sprintf(frame_name2,"Sobel_frame_no_%05u.ppm",i);
			// Load the Image
			src = imread( frame_name2, 1 );
		}

		else
		{
			sprintf(frame_name,"Frame_no_%05u.ppm",i);
			src = imread( frame_name, 1 );
		}

		/*---------------------- Affine Transform : Warp -----------------------*/

		// Setting up the output image parameters

		warp_dst = Mat::zeros( src.rows, src.cols, src.type() );


		/*---------------------- Change the parameter values ----------------------*/

	
	
		switch(section)
		{

			case 0:
			{

				pos[1]=pos[1]+0.001;
				pos[2]=pos[2]-0.001;
				pos[4]=pos[4]+0.001;
				pos[7]=pos[7]-0.001;
		
			
				// Setting parameters for matrix computation

				srcTri[0] = Point2f( 0,0 );
				srcTri[1] = Point2f( src.cols - 1, 0 );
				srcTri[2] = Point2f( 0, src.rows - 1 );
				srcTri[3] = Point2f( src.cols - 1, src.rows - 1 );

				dstTri[0] = Point2f( src.cols*pos[0], src.rows*pos[1] );
				dstTri[1] = Point2f( src.cols*pos[2], src.rows*pos[3] );
				dstTri[2] = Point2f( src.cols*pos[4], src.rows*pos[5] );
				dstTri[3] = Point2f( src.cols*pos[6], src.rows*pos[7] );
			
				section=i/block_size;

				//printf("Case 0: %u\t %f %f %f %f %f %f %f %f\n",i,pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);

				break;
			}

			case 1:
			{

				pos[0]=pos[0]+0.001;
				pos[3]=pos[3]+0.001;
				pos[5]=pos[5]-0.001;
				pos[6]=pos[6]-0.001;
		
			
				// Setting parameters for matrix computation

				srcTri[0] = Point2f( 0,0 );
				srcTri[1] = Point2f( src.cols - 1, 0 );
				srcTri[2] = Point2f( 0, src.rows - 1 );
				srcTri[3] = Point2f( src.cols - 1, src.rows - 1 );

				dstTri[0] = Point2f( src.cols*pos[0], src.rows*pos[1] );
				dstTri[1] = Point2f( src.cols*pos[2], src.rows*pos[3] );
				dstTri[2] = Point2f( src.cols*pos[4], src.rows*pos[5] );
				dstTri[3] = Point2f( src.cols*pos[6], src.rows*pos[7] );
			
				section=i/block_size;

				//printf("Case 1: %u\t %f %f %f %f %f %f %f %f\n",i,pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);

				break;
			}
		
			case 2:
			{
			
				pos[1]=pos[1]-0.001;
				pos[2]=pos[2]+0.001;
				pos[4]=pos[4]-0.001;
				pos[7]=pos[7]+0.001;
		
			
				// Setting parameters for matrix computation

				srcTri[0] = Point2f( 0,0 );
				srcTri[1] = Point2f( src.cols - 1, 0 );
				srcTri[2] = Point2f( 0, src.rows - 1 );
				srcTri[3] = Point2f( src.cols - 1, src.rows - 1 );

				dstTri[0] = Point2f( src.cols*pos[0], src.rows*pos[1] );
				dstTri[1] = Point2f( src.cols*pos[2], src.rows*pos[3] );
				dstTri[2] = Point2f( src.cols*pos[4], src.rows*pos[5] );
				dstTri[3] = Point2f( src.cols*pos[6], src.rows*pos[7] );
			
				section=i/block_size;

				//printf("Case 2: %u\t %f %f %f %f %f %f %f %f\n",i,pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);

				break;
			}
		

			case 3:
			{

				pos[0]=pos[0]-0.001;
				pos[3]=pos[3]-0.001;
				pos[5]=pos[5]+0.001;
				pos[6]=pos[6]+0.001;
		
			
				// Setting parameters for matrix computation

				srcTri[0] = Point2f( 0,0 );
				srcTri[1] = Point2f( src.cols - 1, 0 );
				srcTri[2] = Point2f( 0, src.rows - 1 );
				srcTri[3] = Point2f( src.cols - 1, src.rows - 1 );

				dstTri[0] = Point2f( src.cols*pos[0], src.rows*pos[1] );
				dstTri[1] = Point2f( src.cols*pos[2], src.rows*pos[3] );
				dstTri[2] = Point2f( src.cols*pos[4], src.rows*pos[5] );
				dstTri[3] = Point2f( src.cols*pos[6], src.rows*pos[7] );

			
				section=i/block_size;

				//printf("Case 3: %u\t %f %f %f %f %f %f %f %f\n",i,pos[0],pos[1],pos[2],pos[3],pos[4],pos[5],pos[6],pos[7]);

				break;
			}

			default:
			{
				//printf("Value: %d\n",section);
				//perror("Default switch() case");
				break;
			}
		}
		



		// Calculate the Affine Transform matrix

		warp_mat = getAffineTransform( srcTri, dstTri );


		// Applying the Affine Transform to the src image

		warpAffine( src, warp_dst, warp_mat, warp_dst.size() );



		/*-------------------- Affine Transform : Rotate -----------------------*/

		// Compute the Rotation Matrix Parameters

		Point center = Point( warp_dst.cols/2, warp_dst.rows/2 );
		double angle = ROTATION_ANGLE;
		double scale = ISOTROPIC_SCALE_FACTOR;

		// Generate the Rotation Matrix

		rot_mat = getRotationMatrix2D( center, angle, scale );

		// Rotate the Image

		warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );


		/*------------------------- Storing the Image ---------------------------*/


		sprintf(frame_name3,"Affine_frame_no_%05u.ppm",i);

		// Storing the Image

		imwrite(frame_name3, warp_dst);

	}
	// End of 'for' loop

	return NULL;
}