Documente Academic
Documente Profesional
Documente Cultură
<stdio.h>
<string.h>
<math.h>
<stdlib.h>
<tiffio.h>
#define d1
n in pixels
#define d5
n in pixels
#define d10
in in pixels
#define d25
in in pixels
#define t1
oin
#define t5
oin
#define t10
coin
#define t25
coin
#define size_connect
regions_connect
#define size_search
search_maximum
#define sig
canny edge detector
#define th
edge detector
#define tl
edge detector
#define GV
#define pi
struct edge
nd direction
{
double mag;
int dr, dc;
};
169
185
153
205
80
90
80
90
20
100
40
256
3.141592654
s,
void
void
void
ns);
void
nt32
uint32 columns);
roberts (double *in, struct edge *out, uint32 rows, uint32 columns);
scale (struct edge *in, uint32 rows, uint32 columns);
suppress_nonmaxima (struct edge *in, double *out, uint32 rows, uint32 colum
follow_edge (uint32 er, uint32 ec, double *in, double *out, uint32 rows, ui
columns,
float tlow);
void hough_transform_circles (double *in, int *hough_space, uint32 rows, uint32
columns);
void hough_threshold (int *hough_space, uint32 rows, uint32 columns);
void regions_connect (int *hough_space, int *hough_connect, uint32 rows, uint32
columns);
void hough_label (int *hough_space, int *hough_connect, int label, int *sum, dou
ble *rc,
double *cc, int *n, uint32 r, uint32 c, int i,
uint32 rows, uint32 columns);
void search_maximum (int *hough_space, uint32 rows, uint32 columns);
float count_coins (int *hough_space, uint32 rows, uint32 columns);
void generate_output_image(unsigned char *in_image, unsigned char *out_image, in
t *hough_space, uint32 rows, uint32 columns);
int main()
{
uint32 r;
uint32 c;
uint32 rows;
image
uint32 columns;
mage
uint16 BitsPerSample;
mage
uint16 SamplesPerPixel;
uint16 PhotoMetric;
le image
unsigned char *in_image;
ray
unsigned char *out_image;
rray
TIFF *in_filep;
mage file
TIFF *out_filep;
int check_io;
char input[20];
char in_name[24];
char out_name[28];
char mess[55];
double *tmp1_image;
int *hough_space;
ugh transform
int *hough_connect;
e Hough space
int label;
applied
int sum;
ough space
// row index
// column index
// number of rows in
// number of columns in i
// normally 8 for grayscale i
// normally 1 for grayscale image
// normally 1 for graysca
// pointer for input image ar
// pointer for output image a
// handle for input i
// handle for output image file
// status of I/O operation
// input string
// input file name
// output file name
// error message
// holds temporary image 1
// parameter space for the Ho
// holds the components of th
// belonging together
// holds the next label to be
// to a connected component
// sum of the values in the H
int n;
to one component
int i;
in the Hough space
double rc, cc;
e centroid
uint32 r_centroid, c_centroid;
e centroid
float coins;
s
");
r, c, i, rows, columns)
;
r_centroid = rc;
c_centroid = cc;
hough_space[i*rows*columns+r_centroid*co
lumns+c_centroid] = sum;
}
// search for maximum
search_maximum (hough_space, rows, columns);
// count coins
coins = count_coins (hough_space, rows, columns);
printf("\n");
printf("detected value:
printf("\n");
/*****************************************************
Function name: canny_edge_detect
Description:
detects edges in an input image using a Canny edge
detector and stores the result in an output image
Input parameters:
in_image
-- pointer to input image
out_image
-- pointer to output image
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void canny_edge_detect (unsigned char *in_image, double *out_image, float sigma,
float tlow,
float thigh, uint32 rows, uint32
columns)
{
uint32 r;
// row index
uint32 c;
// column index
double *tmp1_image;
// holds temporary image 1
struct edge *tmp2_image;
// holds temporary image 2
// allocate memory to hold temporary images
tmp1_image = (double *) calloc(rows*columns, sizeof(double));
if(tmp1_image == NULL)
print_error ("Could not allocate memory!");
tmp2_image = (struct edge *) calloc(rows*columns, sizeof(struct edge));
if(tmp2_image == NULL)
print_error ("Could not allocate memory!");
// initialize output image
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
out_image[r*columns+c] = 0;
// applying of the Gaussian mask to the image
gaussian_filtering (in_image, tmp1_image, sigma, rows, columns);
// computing of magnitude and direction of edges using the Roberts operator
roberts (tmp1_image, tmp2_image, rows, columns);
// scale the temporary image
scale (tmp2_image, rows, columns);
// suppress nonmaxima
suppress_nonmaxima (tmp2_image, tmp1_image, rows, columns);
// edge detect
printf("edge detect\n");
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
if(tmp1_image[r*columns+c] >= thigh)
// if pixel val
ue over the higher threshold,
follow_edge(r, c, tmp1_image, out_image, rows, c
olumns, tlow); // follow the edge
// deallocate the memory
free(tmp1_image);
free(tmp2_image);
}
/*****************************************************
Function name: print_error
Description:
Print an error message, and exit the program.
Input parameters:
err_message -- pointer to string to be printed
Returned value:
none
*****************************************************/
void print_error (char *err_message)
{
fprintf(stderr, "Error: %s\n", err_message);
exit (1);
}
/*****************************************************
Function name: gaussian_filtering
Description:
applies a Gaussian filter to an image
Input parameters:
in
-- pointer to input image
out
-- pointer to output image
sigma
-- sigma of the gaussian mask
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void gaussian_filtering (unsigned char *in, double *out, float sigma, uint32 row
s,
uint32 columns)
{
uint32 r;
// row index
uint32 c;
// column index
int hr, hc;
// holds the indexes used for the
computation
float sum;
// result of the Gaussian fil
ter at one pixel
int s;
// size of the Gaussian filter
int x;
// coordinate for Gaussian ma
sk
int gc;
// column index of the Gaussi
an mask
double *g_filter;
// holds the mask for the Gaussia
n filter
double *tmpg_image;
// holds temporary image
// calculate the size of the for the Gaussian filter
s = 8*sqrt(2)*sigma;
if (div(s,2).rem == 0)
s = s+1;
if (((s+1)/2 > 2*rows) || ((s+1)/2 > 2*columns))
print_error ("Gaussian mask too large!");
printf("size of the Gaussian filter:
%d X %d\n", s, s);
// allocate memory
tmpg_image = (double *) calloc(rows*columns, sizeof(double));
if(tmpg_image == NULL)
print_error ("Could not allocate memory!");
g_filter = (double *) calloc(s, sizeof(double));
if(g_filter == NULL)
print_error ("Could not allocate memory!");
printf("computing the Gaussian mask\n");
// in
if (hc < 0)
// if
// result of the
Gaussian
}
// mask at one pixel
tmpg_image[r*columns+c] = sum;
result to an temporary image
}
// storing the
// vertical
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
{
sum = 0;
for (gc = 0; gc < s; gc++)
{
hr = r + gc - (s-1)/2;
if (hr < 0)
// if
// storing the
// deallocate memory
free(tmpg_image);
free(g_filter);
}
/*****************************************************
Function name: roberts
Description:
applies Roberts operator to an image and stores
the magnitude and dirction in an output image
Input parameters:
in
-- pointer to input image
out
-- pointer to output image
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void roberts (double *in, struct edge *out, uint32 rows, uint32 columns)
{
uint32 r;
// row index
uint32 c;
// column index
int hr, hc;
// holds the indexes used for the
computation
float sum1, sum2;
// result of the Roberts oper
ator at one pixel
double alpha;
// holds the angle
int rr, rc;
// row and column index of th
e Roberts operator
const int roberts1[2][2]
// holds the 1. Roberts operator
= {{1,0},{0,-1}};
const int roberts2[2][2]
// holds the 2. Roberts operator
= {{0,-1},{1,0}};
printf("computing magnitude and direction\n");
// computing of magnitude and direction of edges using the Roberts operator
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
{
sum1 = 0;
sum2 = 0;
for (rr = 0; rr < 2; rr++)
// indexes
//
hc = columns - 1;
if (hr > (rows -1))
hr = rows - 1;
sum1 += roberts1[rr][rc] * in[hr*columns
+hc]; // results of applying
sum2 += roberts2[rr][rc] * in[hr*columns
+hc]; // the Roberts operators
}
out[r*columns+c].mag = sqrt(pow(sum1,2)+pow(sum2,2)); /
/ storing the magnitude
// to tempora
ry image 2
if (sum2 != 0)
// calculation of t
he direction
alpha = atan(sum1/sum2);
else
alpha = pi/2;
if ((alpha < -3*pi/8) || (alpha >= 3*pi/8)) // storing
the direction to temporary
{
// image 2
in terms of +1, 0, -1
out[r*columns+c].dr = 1;
// for rows and c
olumns
out[r*columns+c].dc = 1;
// => 4 direction
s between -pi/2 and +pi/2
}
if ((alpha >= -3*pi/8) && (alpha < -pi/8))
{
out[r*columns+c].dr = 1;
out[r*columns+c].dc = 0;
}
if ((alpha >= -pi/8) && (alpha < pi/8))
{
out[r*columns+c].dr = 1;
out[r*columns+c].dc = -1;
}
if ((alpha >= pi/8) && (alpha < 3*pi/8))
{
out[r*columns+c].dr = 0;
out[r*columns+c].dc = -1;
}
}
}
/*****************************************************
Function name: scale
Description:
scales an image
Input parameters:
in
-- pointer to input image
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void scale (struct edge *in, uint32 rows, uint32 columns)
{
uint32 r;
uint32 c;
double scale_factor;
double max_val;
temporary images
// row index
// column index
// scaling factor
// hold the maximal value of the
printf("scaling\n");
// scale the temporary image
max_val = 0;
hc = 0;
if (hc > (columns -1))
hc = columns - 1;
if (hr < 0)
hr = 0;
if (hr > (rows -1))
hr = rows - 1;
if (in[r*columns+c].mag <= in[hr*columns+hc].mag) // su
ppress nonmaxima
out[r*columns+c] = 0;
else
out[r*columns+c] = in[r*columns+c].mag;
hc = c - in[r*columns+c].dc;
hr = r - in[r*columns+c].dr;
// of the gradient
in the directon
if (hc < 0)
hc = 0;
if (hc > (columns -1))
hc = columns - 1;
if (hr < 0)
hr = 0;
if (hr > (rows -1))
hr = rows - 1;
if (in[r*columns+c].mag <= in[hr*columns+hc].mag) // su
ppress nonmaxima
out[r*columns+c] = 0;
}
}
/*****************************************************
Function name: follow_edge
Description:
follows an edge in an input image and prints
this edge to an output image (has to be initialized)
Input parameters:
er
-- row
ec
-- column
in
-- pointer to input image
out
-- pointer to output image
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void follow_edge (uint32 er, uint32 ec, double *in, double *out, uint32 rows, ui
nt32 columns,
float tlow)
{
int hr, hc;
// row and column index
out[er*columns+ec] = GV-1;
hr = er + 1;
s
printf("performing the Hough transform\n");
// initialize the Hough space
for (rh = 0; rh < rows; rh++)
for (ch = 0; ch < columns; ch++)
for (i = 0; i < 4; i++)
hough_space[i*rows*columns+rh*columns+ch] = 0;
// perform the Hough transform
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
if (in[r*columns+c] == (GV-1))
// compute a circle
for every pixel in the
for (i = 0; i < 4; i++)
// edge image
{
chmin = c - d[i]/2;
// minimum c
olumn value of the circle
chmax = c + d[i]/2;
// maximum c
olumn value of the circle
if (chmin < 0)
// column va
// lie i
{
if (((ch-c) <= d[i]/2) && ((c-ch
) <= d[i]/2))
{
rh = r + sqrt(pow(d[i]/2
, 2) - pow(ch-c, 2));
if (rh < rows)
hough_space[i*ro
ws*columns+rh*columns+ch]
= hough_spac
e[i*rows*columns+rh*columns+ch] +1;
rh = r - sqrt(pow(d[i]/2
, 2) - pow(ch-c, 2));
if (rh >= 0)
hough_space[i*ro
ws*columns+rh*columns+ch]
= hough_spac
e[i*rows*columns+rh*columns+ch] +1;
}
}
}
}
/*****************************************************
Function name: hough_threshold
Describtion:
sets the values less than or equal to
the threshold to 0
Input parameters:
hough_space -- pointer to the 3D array holding
the Hough space
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void hough_threshold (int *hough_space, uint32 rows, uint32 columns)
{
uint32 r;
// row index
uint32 c;
// column index
int i;
// index for the diameters of the circles
const int t[4] = {t10, t1, t5, t25};
// holds the different threshold
s for the
// different diameters
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
for (i = 0; i < 4; i++)
if (hough_space[i*rows*columns+r*columns+c] <= t
[i])
hough_space[i*rows*columns+r*columns+c]
= 0;
}
/*****************************************************
Function name: regions_connect
Description:
connect the regions in the Hough space by placing
a square labeled -1 over every pixel in the
Hough space being larger than 0, the result is
stored in hough_connect
Input parameters:
hough_space -- pointer to the 3D array holding
the Hough space
hough_connect -- pointer to the 3D array holding
the conncted Hough space
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void regions_connect (int *hough_space, int *hough_connect, uint32 rows, uint32
columns)
{
uint32 r;
// row index
uint32 c;
// column index
int i;
// index for the diameters of the circles
uint32 rs, cs;
// row a
nd column index of the squares
uint32 rs_min, rs_max;
// minimum and m
aximum index (row)
uint32 cs_min, cs_max;
// minimum and m
aximum index (column)
const int size = size_connect;
// 1/2 of size of the sq
uares
printf("connect regions\n");
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
for (i = 0; i < 4; i++)
if (hough_space[i*rows*columns+r*columns+c] != 0
)
{
rs_min = r - size;
quare must lie inside the Hough space
if (rs_min < 0)
rs_min = 0;
rs_max = r + size;
if (rs_max >= rows)
rs_max = rows - 1;
cs_min = c - size;
if (cs_min < 0)
cs_min = 0;
cs_max = c + size;
if (cs_max >= columns)
cs_max = columns - 1;
// the s
// apply
compute the s
the row index
the column in
// compu
in the Hough
//
//
rh
ch
if
int i;
// index for the diameter (layer)
int j;
// index for the diameters
uint32 rs, cs;
nd column indexes of the square region
uint32 rs_min, rs_max;
square region
uint32 cs_min, cs_max;
square region
const int size = size_search;
uare region
// row a
// border of the
// border of the
// 1/2 of size of the sq
// squar
hough_space
rows
columns
Returned value:
value of the detected coins
*****************************************************/
float count_coins (int *hough_space, uint32 rows, uint32 columns)
{
uint32 r;
// row index
uint32 c;
// column index
int i;
// index of the diameters
int n;
// number of coins
float count;
// detected value
const float value[4] = {0.10, 0.01, 0.05, 0.25}; // holds the values of
the different coins
printf("counting coins\n");
printf("\n");
count = 0;
// search in Hough space
// if coin detected, add value to count
for (i = 0; i < 4; i++)
{
n = 0;
for (r = 0; r < rows; r++)
for (c = 0; c < columns; c++)
if (hough_space[i*rows*columns+r*columns+c] != 0
)
n++;
count += n * value[i];
printf("number of coins %.2f $:
}
printf("\n");
return count;
}
/*****************************************************
Function name: generate_output_image
Description:
counts the coins detected in the Hough space
Input parameters:
in_image
-- pointer to the input image
out_image
-- pointer to the output image
hough_space -- pointer to the 3D array holding
the Hough space
rows
-- number of rows
columns
-- number of columns
Returned value:
none
*****************************************************/
void generate_output_image(unsigned char *in_image, unsigned char *out_image, in
t *hough_space, uint32 rows, uint32 columns)
{
uint32 r;
// row index
uint32 c;
// column index
int i;
// index of the diameters
uint32 hr, hc;
// indexes for the template
uint32 hr_min, hc_min;
// maxim
al and minimum values for the template
const int number[4][24][26]
// holds
the templates for the numbers
= {{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}},
{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}},
{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}},
{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1},
{1,1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1},
{1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1},
{1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1},
{1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1},
{1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1},
{1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1},
{1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,1},
{1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,1,1},
{1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}};
// write input image in output image