⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testimage.cpp

📁 A tutorial and open source code for finding edges and corners based on the filters used in primary v
💻 CPP
字号:
// TestImage.cpp
/*
** Copyright (C) 2000 Tyler C. Folsom
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation.  This software is provided "as is" without express or
** implied warranty.
*/

#include "stdafx.h"
#include "TestImage.h"
#include "quad_dis.h"

/*------------------------------------------------------------------------*/
void CTestImage::MakeEdge
// Fill in the test image to make an edge with the given contrast.
( int contrast  /* in; gray-scale difference across the edge. */
)
{
    /* dark and light are the two gray levels to use*/
    int ndark = MEDIUM_GRAY - contrast/2;
    PIXEL dark = (PIXEL) (ndark < MIN_PIXEL?
        MIN_PIXEL: ndark);
    int nlight = ndark + contrast;
    PIXEL light = (PIXEL) (nlight > MAX_PIXEL?
        MAX_PIXEL: nlight);

    CRect full = Rect();  // The full test image
    int center = Height() / 2 - 1;
    CRect half = full;
    half.bottom = center; // Upper half of image
    SetRect(half);        // Activate only the upper half.
    FillPixels( light);   // upper half is light
    half = full;        
    half.top = center;    // Lower half of image
    SetRect(half);        // Activate lower half
    FillPixels( dark);    // bottom half is dark
    SetRect(full);        // whole image is active
}
/*------------------------------------------------------------------------*/
void CTestImage::MakeBar( int contrast, int barWidth)
{
    int ndark = MEDIUM_GRAY - contrast/2;
    PIXEL dark = (PIXEL) (ndark < MIN_PIXEL?
        MIN_PIXEL: ndark);
    int nlight = ndark + contrast;
    PIXEL light = (PIXEL) (nlight > MAX_PIXEL?
        MAX_PIXEL: nlight);

    CRect full = Rect();
    FillPixels( dark);  // whole image is dark
    int center = Height() / 2;
    CRect bar = full;
    bar.top = center - barWidth/2;
    bar.bottom = center + (barWidth+1)/2;
    SetRect(bar);
    FillPixels( light);   // add a light bar
    SetRect(full);       // whole image is active
}
/*------------------------------------------------------------------------*/
void CTestImage::MakeCorner
// Fill in the test image to make a corner with the given contrast.
( int contrast  /* in; gray-scale difference across the corner. */
)
{
    /* dark and light are the two gray levels to use*/
    int ndark = MEDIUM_GRAY - contrast/2;
    PIXEL dark = (PIXEL) (ndark < MIN_PIXEL?
        MIN_PIXEL: ndark);
    int nlight = ndark + contrast;
    PIXEL light = (PIXEL) (nlight > MAX_PIXEL?
        MAX_PIXEL: nlight);

    CRect full = Rect();  // The full test image
    int centerUp = Height() / 2 + 1;
    int centerHoriz = Width() / 2 + 1;
    CRect quarter = full;
    quarter.bottom = centerUp; // Upper half of image
    SetRect(quarter);        // Activate only the upper half.
    FillPixels( light);   // upper half is light

    quarter = full;        
    quarter.top = centerUp;    // Lower half of image
	quarter.right = centerHoriz;  // lower left
    SetRect(quarter);        // Activate lower left quarter
    FillPixels( light);    //  Make it light

    quarter = full;        
    quarter.top = centerUp;    // Lower half of image
	quarter.left = centerHoriz;  // lower right
    SetRect(quarter);        // Activate lower right quarter
    FillPixels( dark);    // make it dark
    SetRect(full);        // whole image is active
}
/*------------------------------------------------------------------------*/
void CTestImage::Rotate(int degrees)
{
    CRect bounds = Rect();
    // Retain the old image
    const CTestImage* pNewImage = this;
    CTestImage NewImage = *pNewImage;
    // copy the current image to a new image
    // Copy will make the current image be NewImage
    Copy(NewImage);
    // Do the rotation
    Warp( NewImage, (double) (degrees - 180));
    // Copy new image to current
    Copy(NewImage);
    // delete new image
//  delete pNewImage;
}
/*------------------------------------------------------------------------*/
/* Add Gaussian noise to an image */
void CTestImage::AddNoise
( float sigma )  /* in; Standard deviation for the noise. */
{
   /* Seed the random-number generator with current time so that
    * the numbers will be different every time we run.    */
    srand( (unsigned)time( NULL ) );
    CRect bounds = Rect();
    for (int row = bounds.top; row < bounds.bottom; row++)
    {
        for (int col = bounds.left; col < bounds.right; col++)
        {
            float x = (float) Pixel( col, row);
            float noisy = normal_rv (x, sigma); /* add gaussian noise */
            if (noisy < MIN_PIXEL)
                noisy = MIN_PIXEL;
            if (noisy > MAX_PIXEL)
                noisy = MAX_PIXEL;
            Pixel( col, row) = (PIXEL) (noisy + 0.5);
        }
   }
}
/*------------------------------------------------------------------------*/
/* Returns a normally distributed random variable. */
/* Tyler Folsom  10/28/92 */
float CTestImage::normal_rv 
(   float mean,  /* in; Mean value for the random variable */
    float sigma  /* in: Standard deviation */
)
{
    double r_num;
    float rand_noise;
    static struct density_function
    { double x; double area;}  ndf[] =  /* normal distribution function */
    {0.0, 0.5000,  0.1, 0.5398,  0.2, 0.5793,  0.3, 0.6179,  0.4, 0.6554,
     0.5, 0.6915,  0.6, 0.7257,  0.7, 0.7580,  0.8, 0.7881,  0.9, 0.8159,
     1.0, 0.8413,  1.1, 0.8643,  1.2, 0.8849,  1.3, 0.9032,  1.4, 0.9192,
     1.6, 0.9452,  1.8, 0.9641,  2.0, 0.9772,  2.2, 0.9861,  2.4, 0.9918,
     2.7, 0.9965,  3.0, 0.9987,  3.3, 0.9995,  3.6, 0.9998,  4.0, 1.0000};
    int i;

    r_num = rand() / double (RAND_MAX + 1);
    if (r_num < 0.5)
    {   /* ndf is symmetric about 0.5; reflect it. */
        sigma = -sigma;
        r_num = r_num + 0.5;
    }
    /* make it gaussian */
    for (i = 1; r_num > ndf[i].area; i++)
        ;
    /* Interpolate using ndf[i].x to get rand_noise. */
    rand_noise = (float) (ndf[i-1].x + (r_num - ndf[i-1].area) * 
     (ndf[i].x - ndf[i-1].x) / (ndf[i].area - ndf[i-1].area));

    return (mean + sigma * rand_noise);
}
/*------------------------------------------------------------------------*/
void CTestImage::Warp
(   CTestImage& newImage,
    double rot, // Rotation (degrees)
    double h1, double h2, // Translation (pixels from image center)
    double scale,  // scale factor: new height / old height
    double tilt_ax, // Tilt axis (degrees)
    double tilt    // Tilt angle (degrees)
)
{
    /* multiply coordinates of image by this matrix to get newImage coords */
    double old_new[4];
    /* multiply coordinates of newImage by this matrix to get original coords */
    double new_old[4];

    angles_matrix( scale, rot, tilt_ax, tilt, old_new);
    invert( old_new, new_old);
    warp_it( newImage, new_old, h1, h2);

}
/*----------------------------------------------------------------------*/
/* Convert the warp scale and angles to a linear transform matrix */
void CTestImage::angles_matrix( double scale, double rotat, double tilt_axis, 
    double tilt_angle, double *matrix)
{
    double scale_rot[4], tilts[4];
    double rot, tilt_ax, tilt;
    double cos_axis, sin_axis, cos_beta;

    /* Convert to radians */
    rot = rotat * PI / 180.0;
    tilt_ax = tilt_axis * PI / 180.0;
    tilt = tilt_angle * PI / 180.0;
    /* set up scaling and rotation */
    scale_rot[0] = scale * cos(rot);
    scale_rot[3] = scale_rot[0];
    scale_rot[2] = scale * sin(rot);
    scale_rot[1] = -scale_rot[2];
    /* set up tilt matrix */
    cos_axis = cos(tilt_ax);
    sin_axis = sin(tilt_ax);
    cos_beta = cos(tilt);
    tilts[0] = cos_beta + (1.0 - cos_beta) * cos_axis * cos_axis;
    tilts[1] =
    tilts[2] = (1.0 - cos_beta) * cos_axis * sin_axis;
    tilts[3] = cos_beta + (1.0 - cos_beta) * sin_axis * sin_axis;
    /* multiply these matrices to get transformation */
    matrix[0] = scale_rot[0] * tilts[0] + scale_rot[1] * tilts[2];
    matrix[1] = scale_rot[0] * tilts[1] + scale_rot[1] * tilts[3];
    matrix[2] = scale_rot[2] * tilts[0] + scale_rot[3] * tilts[2];
    matrix[3] = scale_rot[2] * tilts[1] + scale_rot[3] * tilts[3];
}
/*----------------------------------------------------------------------*/
/* Invert a 2x2 matrix */
void CTestImage::invert( double *matrix, double *inverse)
{
    double determinant;

    determinant = matrix[0] * matrix[3] - matrix[1] * matrix[2];
    if (fabs(determinant) <= 1.0e-20)
        determinant = 1.0;
    inverse[0] =  matrix[3] / determinant;
    inverse[1] = -matrix[1] / determinant;
    inverse[2] = -matrix[2] / determinant;
    inverse[3] =  matrix[0] / determinant;
}
/*----------------------------------------------------------------------*/
/* Transform iold to im_new by mapping coordinates:
  (x, y) = (matrix) (x - h1, y - h2)   */
void CTestImage::warp_it( CTestImage& newImage, double matrix[4], double h1, 
 double h2)
{
    CRect bounds = Rect();
    double x_old, y_old;
    int row_old, col_old;
    double x_new, y_new, y1, x1, new_value;

    double center_x = (bounds.right - bounds.left) / 2.0;
    double center_y = (bounds.bottom - bounds.top) / 2.0;
    CRect newSize = newImage.Rect();
    for (int row = newSize.top; row < newSize.bottom; row++)
    {
        y_new = (double) (row - h2);
        for (int col = newSize.left; col < newSize.right; col++)
        {
            x_new = (double) (col - h1);
            x_old = matrix[0] * (x_new - center_x) + matrix[1] * (y_new - 
             center_y) + center_x;
            y_old = matrix[2] * (x_new - center_x) + matrix[3] * (y_new -
             center_y) + center_y;
            row_old = (int) y_old;
            col_old = (int) x_old;

            if (col_old < bounds.left)
            {
                if (row_old < bounds.top)
                    newImage.Pixel(col, row) = Pixel(bounds.left, bounds.top);
                else if (row_old+1 >= bounds.bottom)
                    newImage.Pixel(col, row) = Pixel(bounds.left, bounds.bottom - 1);
                else
                {
                    y1 = y_old - (double) row_old;
                    new_value = y1 * Pixel(bounds.left, row_old+1) +
                     (1.0 - y1) * Pixel(bounds.left, row_old);
                    newImage.Pixel(col, row) = (PIXEL) (new_value + 0.5);
                }
            }
            else if (col_old >= bounds.right - 1)
            {
                if (row_old < bounds.top)
                    newImage.Pixel(col, row) = Pixel(bounds.right-1, bounds.top);
                else if (row_old >= bounds.bottom - 1)
                    newImage.Pixel(col, row) = Pixel(bounds.right-1, bounds.bottom - 1);
                else
                {
                    y1 = y_old - (double) row_old;
                    new_value = y1 * Pixel(bounds.right-1, row_old+1) +
                     (1.0 - y1) * Pixel(bounds.right-1, row_old);
                    newImage.Pixel(col, row) = (PIXEL) (new_value + 0.5);
                }
            }
            else   /* col_old is within bounds. */
            {
                x1 = x_old - (double) col_old;
                if (row_old < bounds.top)
                {
                    new_value = x1 * Pixel( col_old + 1, bounds.top)
                     + (1.0 - x1) * Pixel( col_old, bounds.top);
                }
                else if (row_old >= bounds.bottom - 1)
                {
                    new_value = x1 * Pixel( col_old + 1, bounds.bottom - 1)
                     + (1.0 - x1) * Pixel( col_old, bounds.bottom - 1);
                }
                else   /* Everything is within bounds */
                {
                    y1 = y_old - (double) row_old;
                    new_value = y1 * (x1 * Pixel( col_old + 1, row_old + 1)
                     + (1.0 - x1) * Pixel( col_old, row_old + 1))
                     + (1.0 - y1) * (x1 * Pixel( col_old + 1, row_old)
                     + (1.0 - x1) * Pixel( col_old, row_old));
                }   /* end of row_old if */
                newImage.Pixel(col, row) = (PIXEL) (new_value + 0.5);
            }   /* end of col_old if */
        }   /* end of loop on col */
    }   /* end of loop on row */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -