void DS3231::setDateTime(const char* date, const char* time) { uint16_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; year = conv2d(date + 9); switch (date[0]) { case 'J': month = date[1] == 'a' ? 1 : month = date[2] == 'n' ? 6 : 7; break; case 'F': month = 2; break; case 'A': month = date[2] == 'r' ? 4 : 8; break; case 'M': month = date[2] == 'r' ? 3 : 5; break; case 'S': month = 9; break; case 'O': month = 10; break; case 'N': month = 11; break; case 'D': month = 12; break; } day = conv2d(date + 4); hour = conv2d(time); minute = conv2d(time + 3); second = conv2d(time + 6); setDateTime(year+2000, month, day, hour, minute, second); }
// A convenient constructor for using "the compiler's time": // DateTime now (__DATE__, __TIME__); // NOTE: using PSTR would further reduce the RAM footprint DateTime::DateTime (const char* date, const char* time) { // sample input: date = "Dec 26 2009", time = "12:34:56" yOff = conv2d(date + 9); // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (date[0]) { case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; case 'F': m = 2; break; case 'A': m = date[2] == 'r' ? 4 : 8; break; case 'M': m = date[2] == 'r' ? 3 : 5; break; case 'S': m = 9; break; case 'O': m = 10; break; case 'N': m = 11; break; case 'D': m = 12; break; } d = conv2d(date + 4); hh = conv2d(time); mm = conv2d(time + 3); ss = conv2d(time + 6); }
void RTCDue::setTime (const char* time) { _hour = conv2d(time); _minute = conv2d(time + 3); _second = conv2d(time + 6); RTC_SetTime (RTC, _hour, _minute, _second); }
// Marr-Hildreth edge detector with Gaussian and Laplacian kernels // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float sigma - gaussian standard deviation // int n - kernel size // float tzc - threshold in zero-crossing // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_mh(float *im, int w, int h, float sigma, int n, float tzc, int padding_method) { // generate Gaussian kernel float *kernel = gaussian_kernel(n,sigma); // smooth input image with the Gaussian kernel float *im_smoothed = conv2d(im, w, h, kernel, n, padding_method); // compute Laplacian of the smoothed image using a 3x3 operator float operator[9] = {1, 1, 1, 1, -8, 1, 1, 1, 1}; float *laplacian = conv2d(im_smoothed, w+n-1, h+n-1, operator, 3, padding_method); // compute maximum of absolute Laplacian float max = 0.0; for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { //laplacian is (w+n+1)x(h+n+1) with an offset of (n+1)/2 in x and y float v = abs( laplacian[(i+(n+1)/2) + (j+(n+1)/2)*(w+n+1)] ); if( v > max ) max = v; } } // compute laplacian zero-crossings float *edges = xmalloc(w*h*sizeof(float)); for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { //laplacian is (w+n+1)x(h+n+1) with an offset of (n+1)/2 in x and y float UP_LE = laplacian[ (i-1+(n+1)/2) + (j+1+(n+1)/2)*(w+n+1) ]; float UP = laplacian[ (i +(n+1)/2) + (j+1+(n+1)/2)*(w+n+1) ]; float UP_RI = laplacian[ (i+1+(n+1)/2) + (j+1+(n+1)/2)*(w+n+1) ]; float LE = laplacian[ (i-1+(n+1)/2) + (j +(n+1)/2)*(w+n+1) ]; float RI = laplacian[ (i+1+(n+1)/2) + (j +(n+1)/2)*(w+n+1) ]; float DO_LE = laplacian[ (i-1+(n+1)/2) + (j-1+(n+1)/2)*(w+n+1) ]; float DO = laplacian[ (i +(n+1)/2) + (j-1+(n+1)/2)*(w+n+1) ]; float DO_RI = laplacian[ (i+1+(n+1)/2) + (j-1+(n+1)/2)*(w+n+1) ]; if( (LE*RI < 0.0 && abs(LE-RI) > tzc*max) || (UP_LE*DO_RI < 0.0 && abs(UP_LE-DO_RI) > tzc*max) || (DO_LE*UP_RI < 0.0 && abs(DO_LE-UP_RI) > tzc*max) || (UP*DO < 0.0 && abs(UP-DO) > tzc*max) ) { edges[i+j*w] = 255.0; } else { edges[i+j*w] = 0.0; } } } // free memory free(kernel); free(im_smoothed); free(laplacian); return edges; }
DateTime::DateTime (const char* date, const char* time) : yOff(conv2d(date + 9)), m(0), d(conv2d(date + 4)), hh(conv2d(time)), mm(conv2d(time + 3)), ss(conv2d(time + 6)) { // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (date[0]) { case 'J': m = (date[1] == 'a') ? 1 : (date[2] == 'n') ? 6 : 7; break; case 'F': m = 2; break; case 'A': m = date[2] == 'r' ? 4 : 8; break; case 'M': m = date[2] == 'r' ? 3 : 5; break; case 'S': m = 9; break; case 'O': m = 10; break; case 'N': m = 11; break; case 'D': m = 12; break; } }
DateTime::DateTime (const char* date, const char* time) { yOff = conv2d(date + 9); switch(date[0]) { case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; case 'F': m = 2; break; case 'A': m = date[2] == 'r' ? 4 : 8; break; case 'M': m = date[2] == 'r' ? 3 : 5; break; case 'S': m = 9; break; case 'O': m = 10; break; case 'N': m = 11; break; case 'D': m = 12; break; } d=conv2d(date+4); hh=conv2d(time); mm=conv2d(time+3); ss=conv2d(time+6); }
// Roberts edge detector // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float threshold - threshold of edge detection // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_roberts(float *im, int w, int h, float threshold, int padding_method) { // Define operators // 3x3 operators are used (although it is unnecessary) in order to // simplify the convolution application, and also to unify the three // detectors of the first family. float roberts_1[9] = {-1, 0, 0, 0, 1, 0, 0, 0, 0}; // ROBERTS float roberts_2[9] = { 0,-1, 0, 1, 0, 0, 0, 0, 0}; // OPERATORS for(int z=0; z<9; z++) { // normalization roberts_1[z] /= 2.0; roberts_2[z] /= 2.0; } // Convolution with operators float *Gx = conv2d(im, w, h, roberts_1, 3, padding_method); float *Gy = conv2d(im, w, h, roberts_2, 3, padding_method); // Allocate memory for output image float *im_roberts = xmalloc(w*h*sizeof(float)); // Two images are obtained (one for each operator). Then the gradient // magnitude image is constructed using sqrt(g_x^2+g_y^2). Also // the absolute maximum value of the constructed images is computed float max = 0.0; for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { float gx = Gx[i+1 + (j+1)*(w+2)]; // Gx and Gy are (w+2) x (h+2) float gy = Gy[i+1 + (j+1)*(w+2)]; // there is an (+1,+1) offset im_roberts[i+j*w] = sqrt(gx*gx + gy*gy); max = MAX(max, im_roberts[i+j*w]); } } // Threshold for(int i=0; i<w*h; i++) { im_roberts[i] = THRESHOLD(im_roberts[i], threshold*max); } // Free memory free(Gx); free(Gy); return im_roberts; }
// Sobel edge detector // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float threshold - threshold of edge detection // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_sobel(float *im, int w, int h, float threshold, int padding_method) { // Define operators float sobel_1[9] = {-1,-2,-1, 0, 0, 0, 1, 2, 1}; // SOBEL float sobel_2[9] = {-1, 0, 1,-2, 0, 2,-1, 0, 1}; // OPERATORS for(int z=0; z<9; z++) { // normalization sobel_1[z] /= 8.0; sobel_2[z] /= 8.0; } // Convolution with operators float *Gx = conv2d(im, w, h, sobel_1, 3, padding_method); float *Gy = conv2d(im, w, h, sobel_2, 3, padding_method); // Allocate memory for output image float *im_sobel = xmalloc(w*h*sizeof(float)); // Two images are obtained (one for each operator). Then the gradient // magnitude image is constructed using sqrt(g_x^2+g_y^2). Also // the absolute maximum value of the constructed images is computed float max = 0.0; for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { float gx = Gx[i+1 + (j+1)*(w+2)]; // Gx and Gy are (w+2) x (h+2) float gy = Gy[i+1 + (j+1)*(w+2)]; // there is an (+1,+1) offset im_sobel[i+j*w] = sqrt(gx*gx + gy*gy); max = MAX(max, im_sobel[i+j*w]); } } // Threshold for(int i=0; i<w*h; i++) { im_sobel[i] = THRESHOLD(im_sobel[i], threshold*max); } // Free memory free(Gx); free(Gy); return im_sobel; }
/** * Geklaut von Jee-Labs. * A convenient constructor for using "the compiler's time": * DateTime now (__DATE__, __TIME__); * NOTE: using PSTR would further reduce the RAM footprint */ void MyRTC::set(const char* date, const char* time) { // sample input: date = "Dec 26 2009", time = "12:34:56" _year = conv2d(date + 9); // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (date[0]) { case 'J': if (date[1] == 'a') { _month = 1; } else if (date[2] == 'n') { _month = 6; } else { _month = 7; } break; case 'F': _month = 2; break; case 'A': _month = date[2] == 'r' ? 4 : 8; break; case 'M': _month = date[2] == 'r' ? 3 : 5; break; case 'S': _month = 9; break; case 'O': _month = 10; break; case 'N': _month = 11; break; case 'D': _month = 12; break; } _date = conv2d(date + 4); _hours = conv2d(time); _minutes = conv2d(time + 3); _seconds = conv2d(time + 6); }
// A convenient constructor for using "the compiler's time": // DateTime now (__DATE__, __TIME__); // NOTE: using PSTR would further reduce the RAM footprint DateTime::DateTime( const char *date, const char *time, uint32_t centisecond) : centisecond_(centisecond) { // sample input: date = "Dec 26 2009", time = "12:34:56" year_ = conv2d(date + 9); // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (date[0]) { case 'J': month_ = date[1] == 'a' ? 1 : (month_ = date[2] == 'n' ? 6 : 7); break; case 'F': month_ = 2; break; case 'A': month_ = date[2] == 'r' ? 4 : 8; break; case 'M': month_ = date[2] == 'r' ? 3 : 5; break; case 'S': month_ = 9; break; case 'O': month_ = 10; break; case 'N': month_ = 11; break; case 'D': month_ = 12; break; default: break; } day_ = conv2d(date + 4); hour_ = conv2d(time); minute_ = conv2d(time + 3); second_ = conv2d(time + 6); }
// Based on https://github.com/adafruit/RTClib/blob/master/RTClib.cpp void RTCDue::setDate (const char* date) { _day = conv2d(date + 4); //Month switch (date[0]) { case 'J': _month = date[1] == 'a' ? 1 : _month = date[2] == 'n' ? 6 : 7; break; case 'F': _month = 2; break; case 'A': _month = date[2] == 'r' ? 4 : 8; break; case 'M': _month = date[2] == 'r' ? 3 : 5; break; case 'S': _month = 9; break; case 'O': _month = 10; break; case 'N': _month = 11; break; case 'D': _month = 12; break; } _year = conv2d(date + 7); _day_of_week = calculateDayofWeek(_year, _month, _day); RTC_SetDate (RTC, (uint16_t)_year, (uint8_t)_month, (uint8_t)_day, (uint8_t)_day_of_week); }
// A convenient constructor for using "the compiler's time": // This version will save RAM by using PROGMEM to store it by using the F macro. // DateTime now (F(__DATE__), F(__TIME__)); DateTime::DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time) { // sample input: date = "Dec 26 2009", time = "12:34:56" char buff[11]; memcpy_P(buff, date, 11); yOff = conv2d(buff + 9); // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (buff[0]) { case 'J': m = buff[1] == 'a' ? 1 : m = buff[2] == 'n' ? 6 : 7; break; case 'F': m = 2; break; case 'A': m = buff[2] == 'r' ? 4 : 8; break; case 'M': m = buff[2] == 'r' ? 3 : 5; break; case 'S': m = 9; break; case 'O': m = 10; break; case 'N': m = 11; break; case 'D': m = 12; break; } d = conv2d(buff + 4); memcpy_P(buff, time, 8); hh = conv2d(buff); mm = conv2d(buff + 3); ss = conv2d(buff + 6); }
std::vector < Derived > lidarBoostEngine::lk_optical_flow( const MatrixBase<Derived>& I1, const MatrixBase<Derived> &I2, int win_sz) { //Instantiate optical flow matrices std::vector < Derived > uv(2); //Create masks Matrix2d robX, robY, robT; robX << -1, 1, -1, 1; robY << -1, -1, 1, 1; robT << -1, -1, -1, -1; Derived Ix, Iy, It, A, solutions, x_block, y_block, t_block; //Apply masks to images and average the result Ix = 0.5 * ( conv2d( I1, robX ) + conv2d( I2, robX ) ); Iy = 0.5 * ( conv2d( I1, robY ) + conv2d( I2, robY ) ); It = 0.5 * ( conv2d( I1, robT ) + conv2d( I2, robT ) ); uv[0] = Derived::Zero( I1.rows(), I1.cols() ); uv[1] = Derived::Zero( I1.rows(), I1.cols() ); int hw = win_sz/2; for( int i = hw+1; i < I1.rows()-hw; i++ ) { for ( int j = hw+1; j < I1.cols()-hw; j++ ) { //Take a small block of window size in the filtered images x_block = Ix.block( i-hw, j-hw, win_sz, win_sz); y_block = Iy.block( i-hw, j-hw, win_sz, win_sz); t_block = It.block( i-hw, j-hw, win_sz, win_sz); //Convert these blocks in vectors Map<Derived> A1( x_block.data(), win_sz*win_sz, 1); Map<Derived> A2( y_block.data(), win_sz*win_sz, 1); Map<Derived> B( t_block.data(), win_sz*win_sz, 1); //Organize the vectors in a matrix A = Derived( win_sz*win_sz, 2 ); A.block(0, 0, win_sz*win_sz, 1) = A1; A.block(0, 1, win_sz*win_sz, 1) = A2; //Solve the linear least square system solutions = (A.transpose() * A).ldlt().solve(A.transpose() * B); //Insert the solutions in the optical flow matrices uv[0](i, j) = solutions(0); uv[1](i, j) = solutions(1); } } return uv; }
/* * === FUNCTION ====================================================================== * Name: ConvPoolLayer::conv2d * Description: This function is used for multiple input 2d-image-convolution with multiple kernels, in 'valid' mode * i.e. to colvolve each input image with each kernel * Arguments: maps_input: input images to be convolved * kernels: convolution kernels * maps_conved: convolved maps * ===================================================================================== */ void ConvPoolLayer::conv2d(const vector<MatrixXd>& maps_input, const vector<MatrixXd> kernels, vector<MatrixXd>& maps_conved) { maps_conved.clear(); maps_conved.reserve(kernels.size() * maps_input.size()); // number of output maps is equal to the number of input maps times the number of kernels MatrixXd map_conved_temp; // map_conved_temp is a temporary convolved map to store one single convolution operation for(int i = 0; i < kernels.size(); i++) { for(int j = 0; j < maps_input.size(); j++) { conv2d(maps_input[i], kernels[j], map_conved_temp); maps_conved.push_back(map_conved_temp); } } } /* ----- end of function ConvPoolLayer::conv2d ----- */
// Marr-Hildreth edge detector with Laplacian of Gaussian kernel // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float sigma - gaussian standard deviation // int n - kernel size // float tzc - threshold in zero-crossing // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_mh_log(float *im, int w, int h, float sigma, int n, float tzc, int padding_method) { // compute Laplacian using a LoG (Laplacian of Gaussian) kernel float *kernel = LoG_kernel(n,sigma); float *laplacian = conv2d(im, w, h, kernel, n, padding_method); // compute maximum of absolute Laplacian float max = 0.0; for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { // laplacian is (w+n-1)x(h+n-1) with an offset of (n-1)/2 in x and y float v = abs( laplacian[(i+(n-1)/2) + (j+(n-1)/2)*(w+n-1)] ); if( v > max ) max = v; } } // compute laplacian zero-crossings float *edges = xmalloc(w*h*sizeof(float)); for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { // laplacian is (w+n-1)x(h+n-1) with an offset of (n-1)/2 in x and y float UP_LE = laplacian[ (i-1+(n-1)/2) + (j+1+(n-1)/2)*(w+n-1) ]; float UP = laplacian[ (i +(n-1)/2) + (j+1+(n-1)/2)*(w+n-1) ]; float UP_RI = laplacian[ (i+1+(n-1)/2) + (j+1+(n-1)/2)*(w+n-1) ]; float LE = laplacian[ (i-1+(n-1)/2) + (j +(n-1)/2)*(w+n-1) ]; float RI = laplacian[ (i+1+(n-1)/2) + (j +(n-1)/2)*(w+n-1) ]; float DO_LE = laplacian[ (i-1+(n-1)/2) + (j-1+(n-1)/2)*(w+n-1) ]; float DO = laplacian[ (i +(n-1)/2) + (j-1+(n-1)/2)*(w+n-1) ]; float DO_RI = laplacian[ (i+1+(n-1)/2) + (j-1+(n-1)/2)*(w+n-1) ]; if( (LE*RI < 0.0 && abs(LE-RI) > tzc*max) || (UP_LE*DO_RI < 0.0 && abs(UP_LE-DO_RI) > tzc*max) || (DO_LE*UP_RI < 0.0 && abs(DO_LE-UP_RI) > tzc*max) || (UP*DO < 0.0 && abs(UP-DO) > tzc*max) ) { edges[i+j*w] = 255.0; } else { edges[i+j*w] = 0.0; } } } // free memory free(kernel); free(laplacian); return edges; }
void ConvPoolLayer::bp_weight(const vector<MatrixXd>& grad_conved, const vector<MatrixXd>& maps_input, const int& weight_size, vector<MatrixXd>& grad_weight_single) { grad_weight_single.clear(); MatrixXd grad_weight_temp(weight_size, weight_size); MatrixXd grad_weight_partial; int num_input = maps_input.size(); int num_kernel = grad_conved.size() / num_input; grad_weight_single.reserve(num_kernel); for(int i = 0; i < num_kernel; i++) { grad_weight_partial.setZero(weight_size, weight_size); for(int j = 0; j < num_input; j++) { int index = i * num_input + j; conv2d(maps_input[j], grad_conved[index], grad_weight_temp); grad_weight_partial += grad_weight_temp; } grad_weight_single.push_back(grad_weight_partial); } }
void RTC_set_default_time_to_compiled(void) { uint8_t month_as_number; switch (__DATE__[0]) { case 'J': month_as_number = __DATE__[1] == 'a' ? 1 : __DATE__[2] == 'n' ? 6 : 7; break; case 'F': month_as_number = 2; break; case 'A': month_as_number = __DATE__[2] == 'r' ? 4 : 8; break; case 'M': month_as_number = __DATE__[2] == 'r' ? 3 : 5; break; case 'S': month_as_number = 9; break; case 'O': month_as_number = 10; break; case 'N': month_as_number = 11; break; case 'D': month_as_number = 12; break; } RTC_time_SetTime( conv2d(__DATE__ + 7)*100 + conv2d(__DATE__ + 9), month_as_number, conv2d(__DATE__ + 4), conv2d(__TIME__), conv2d(__TIME__ + 3), conv2d(__TIME__ + 6), 0); }
int main (int argc, char * argv[]) { APPROX int * frame; APPROX int * output; int i; int nFilterRowsFD = 9; int nFilterColsFD = 9; APPROX fltPixel_t FD[] = { 1, 3, 4, 5, 6, 5, 4, 3, 1, 3, 9, 12, 15, 18, 15, 12, 9, 3, 4, 12, 16, 20, 24, 20, 16, 12, 4, 5, 15, 20, 25, 30, 25, 20, 15, 5, 6, 18, 24, 30, 36, 30, 24, 18, 6, 5, 15, 20, 25, 30, 25, 20, 15, 5, 4, 12, 16, 20, 24, 20, 16, 12, 4, 3, 9, 12, 15, 18, 15, 12, 9, 3, 1, 3, 4, 5, 6, 5, 4, 3, 1 }; for (i = 0; i < nFilterRowsFD * nFilterColsFD; i++) // ACCEPT_FORBID { FD[i] /= (1024.0); } srand (time (NULL)); STATS_INIT (); PRINT_STAT_STRING ("kernel", "2d_convolution"); PRINT_STAT_INT ("rows", N); PRINT_STAT_INT ("columns", M); PRINT_STAT_INT ("num_frames", BATCH_SIZE); frame = calloc (M * N * BATCH_SIZE, sizeof(algPixel_t)); output = calloc (M * N * BATCH_SIZE, sizeof(algPixel_t)); if (!frame || !output) { fprintf(stderr, "ERROR: Allocation failed.\n"); exit(-1); } /* load image */ tic (); read_array_from_octave (ENDORSE(frame), N, M, FILENAME); PRINT_STAT_DOUBLE ("time_load_image", toc ()); /* Make BATCH_SIZE-1 copies */ tic (); for (i = 1; i < BATCH_SIZE; i++) // ACCEPT_FORBID { memcpy (&frame[i * M * N], frame, M * N * sizeof(algPixel_t)); } PRINT_STAT_DOUBLE ("time_copy", toc ()); /* Perform the 2D convolution */ tic (); accept_roi_begin(); for (i = 0; i < BATCH_SIZE; i++) // ACCEPT_FORBID { conv2d (&frame[i * M * N], &output[i * M * N], N, M, FD, 1.0, nFilterRowsFD, nFilterColsFD); } accept_roi_end(); PRINT_STAT_DOUBLE ("time_2d_convolution", toc ()); /* Write the results out to disk */ for (i = 0; i < BATCH_SIZE; i++) // ACCEPT_FORBID { char buffer [30]; sprintf (buffer, "2dconv_output.%d.mat", i); write_array_to_octave (ENDORSE(&output[i * M * N]), N, M, buffer, "output_" SIZE); } PRINT_STAT_STRING ("output_file", "2dconv_output." SIZE ".#.mat"); STATS_END (); free (output); free (frame); return 0; }
static uint8_t conv2d(const char* p) { uint8_t v = 0; if ('0' <= *p && *p <= '9') v = *p - '0'; return 10 * v + *++p - '0'; } Adafruit_ILI9341_AS tft = Adafruit_ILI9341_AS(__cs, __dc, __rst); // Invoke custom library float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; // Saved H, M, S x & y multipliers float sdeg=0, mdeg=0, hdeg=0; uint16_t osx=120, osy=120, omx=120, omy=120, ohx=120, ohy=120; // Saved H, M, S x & y coords uint16_t x0=0, x1=0, y0=0, y1=0; uint32_t targetTime = 0; // for next 1 second timeout uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6); // Get H, M, S from compile time boolean initial = 1; void loop() { // if (targetTime < millis()) { // targetTime = millis()+1000; _delay_ms(1000); ss++; // Advance second if (ss==60) { ss=0; mm++; // Advance minute if(mm>59) { mm=0; hh++; // Advance hour if (hh>23) { hh=0;
int main(int argc, char *argv[]) { if (argc != 6) { printf("Usage: %s input_image_1 sigma n tzc output\n", argv[0]); } else { // Execution time: double start = (double)clock(); // Parameters float sigma = atof(argv[2]); // <sigma> is the standard deviation of the gaussian function used to // create the kernel. int n = atoi(argv[3]); // <n> is the size of the kernel (n*n). float tzc = atof(argv[4]); // <tzc> is the threshold of the zero-crossing method. // Load input image (using iio) int w, h, pixeldim; float *im_orig = iio_read_image_float_vec(argv[1], &w, &h, &pixeldim); fprintf(stderr, "Input image loaded:\t %dx%d image with %d channel(s).\n", w, h, pixeldim); // Grayscale conversion (if necessary) double *im = malloc(w*h*sizeof(double)); if (im == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } // allocate memory for the grayscale image <im>, output of the grayscale conversion // and correct allocation check. int z; // <z> is just an integer used as array index. int zmax = w*h; // number of elements of <im> if (pixeldim==3){ // if the image is color (RGB, three channels)... for(z=0;z<zmax;z++){ // for each pixel in the image <im>, calculate the gray // value according to the expression: // I = ( 6968*R + 23434*G + 2366*B ) / 32768. im[z] = (double)(6968*im_orig[3*z] + 23434*im_orig[3*z + 1] + 2366*im_orig[3*z + 2])/32768; } fprintf(stderr, "images converted to grayscale\n"); } else { // the image was originally grayscale... for(z=0;z<zmax;z++){ im[z] = (double)im_orig[z]; // only assign the value of im_orig to im, casting to double. } fprintf(stderr, "images are already in grayscale\n"); } // Generate gaussian kernel // see gaussian_kernel.c double *kernel = gaussian_kernel(n,sigma); // Debug: save kernel to image (this is not part of the algorithm itself) if (SAVE_KERNEL){ float *kernel_float = malloc(n*n*sizeof(float)); if (kernel_float == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } int i; int imax = n*n; for (i=0;i<imax;i++){ kernel_float[i] = 5000*(float)kernel[i]; } iio_save_image_float_vec("kernel.png", kernel_float, n, n, 1); free(kernel_float); fprintf(stderr, "kernel saved to kernel.png\n"); } // end of save kernel image // Smooth input image with gaussian kernel // see 2dconvolution.c // <im_smoothed> is calculated convolving the grayscale image <im> with // the gaussian kernel previously generated. double *im_smoothed = conv2d(im, w, h, kernel, n); // Debug: save smoothed image (this is not part of the algorithm itself) if (SAVE_SMOOTHED_IMAGE){ float *smoothed = malloc((w+n-1)*(h+n-1)*sizeof(float)); if (smoothed == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } int i,j, fila, col; int imax = w*h; int dif_fila_col = (n-1)/2; for (i=0;i<imax;i++){ fila = (int)(i/w); col = i - w*fila + dif_fila_col; fila += dif_fila_col; j = col + (w+n-1)*fila; smoothed[i] = (float)im_smoothed[j]; } iio_save_image_float_vec("smoothed.png", smoothed, w, h, 1); free(smoothed); fprintf(stderr, "smoothed image saved to smoothed.png\n"); } // end of save smoothed image // Laplacian of the smoothed image double operator[9] = {1, 1, 1, 1, -8, 1, 1, 1, 1}; // an approximation of the laplacian operator: // / 1 1 1 \ // | 1 -8 1 | // \ 1 1 1 / // now we convolve the smoothed image with this operator, // generating the <laplacian> image. double *laplacian = conv2d(im_smoothed, w+n-1, h+n-1, operator, 3); // calculate max absolute value of laplacian: // required for thresholding in zero-crossing (next) double max_l = 0; int p; int pmax = (w+n+1)*(h+n+1); for (p=0;p<pmax;p++){ if (abs(laplacian[p])>max_l){ max_l = abs(laplacian[p]); } } // Debug: save laplacian image (this is not part of the algorithm itself) if (SAVE_LAPLACIAN_IMAGE){ float *lapl = malloc((w+n+1)*(h+n+1)*sizeof(float)); if (lapl == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } int i,j, fila, col; int imax = w*h; int dif_fila_col = (n+1)/2; for (i=0;i<imax;i++){ fila = (int)(i/w); col = i - w*fila + dif_fila_col; fila += dif_fila_col; j = col + (w+n+1)*fila; lapl[i] = (float)laplacian[j]; } iio_save_image_float_vec("laplacian.png", lapl, w, h, 1); free(lapl); fprintf(stderr, "laplacian image saved to laplacian.png\n"); } // end of save laplacian image // Zero-crossing float *zero_cross = calloc(w*h,sizeof(float)); // this image will only content values 0 and 255 // but we use float for saving with iio. if (zero_cross == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } int ind_en_lapl, fila, col; int *offsets = get_neighbors_offset(w+n+1, 3); pmax = w*h; int dif_fila_col = (n+1)/2; for (p=0;p<pmax;p++){ fila = ((int)(p/w)); col = p-(w*fila) + dif_fila_col; fila += dif_fila_col; ind_en_lapl = col + (w+n+1)*fila; double *n3 = get_neighborhood(laplacian, ind_en_lapl, 3, offsets); if ((n3[3]*n3[5]<0)&&(abs(n3[3]-n3[5])>(tzc*max_l))) { // horizontal sign change zero_cross[p] = 255; } else if ((n3[1]*n3[7]<0)&&(abs(n3[1]-n3[7])>(tzc*max_l))) { // vertical sign change zero_cross[p] = 255; } else if ((n3[2]*n3[6]<0)&&(abs(n3[2]-n3[6])>(tzc*max_l))) { // +45deg sign change zero_cross[p] = 255; } else if ((n3[0]*n3[8]<0)&&(abs(n3[0]-n3[8])>(tzc*max_l))) { // -45deg sign change zero_cross[p] = 255; } free_neighborhood(n3); } free_neighbors_offsets(offsets); // Save output image iio_save_image_float_vec(argv[5], zero_cross, w, h, 1); fprintf(stderr, "Output Image saved in %s:\t %dx%d image with %d channel(s).\n", argv[5], w, h, pixeldim); // Free memory free(zero_cross); free(im_orig); free(im); free(im_smoothed); free(laplacian); free_gaussian_kernel(kernel); fprintf(stderr, "marr-hildreth edge detector computation done.\n"); // Execution time: double finish = (double)clock(); double exectime = (finish - start)/CLOCKS_PER_SEC; fprintf(stderr, "execution time: %1.3f s.\n", exectime); return 0; } // else (argc) }
bool SerialLineIn::dispatch(void) { bool handled = false; DateTime now = RTC.nowDateTime(); switch (toupper(*buf)) { case 'D': // Dyymmdd: Set date handled = true; if ( strlen(buf) == 1 ) { print_time(); break; } if ( strlen(buf) != 7 ) { printf_P(PSTR("SERL Format: Dyymmdd\n\r")); break; } now = DateTime(2000+conv2d(buf+1),conv2d(buf+3),conv2d(buf+5),now.hour(),now.minute(),now.second()); RTC.adjust(now); print_time(); break; case 'T': // Thhmmss: Set time handled = true; if ( strlen(buf) != 7 ) { printf_P(PSTR("SERL Format: Dyymmdd\n\r")); break; } now = DateTime(now.year(),now.month(),now.day(),conv2d(buf+1),conv2d(buf+3),conv2d(buf+5)); RTC.adjust(now); print_time(); break; case '@': handled = true; // Special time values if ( !strcmp(buf+1,"N") ) { uint32_t when = events.whenNext(); #ifdef HAVE_FIRE_CAMERA if ( fire_camera.is_valid() ) when = fire_camera.whenNext(); #endif RTC.adjust(when); print_time(); } else if ( !strcmp(buf+1,"1") ) { events.reset(); #ifdef HAVE_FIRE_CAMERA fire_camera.invalidate(); #endif RTC.adjust(events.whenNext()); print_time(); } else if ( !strcmp(buf+1,"0") ) { RTC.adjust(DateTime(2011,1,1,0,0,0).unixtime()); print_time(); } else printf_P(PSTR("SERL Error: Unknown @ value: %s"),buf+1); break; case 'E': // E: Print EEPROM handled = true; logger.play(); break; case 'F': // F: Free memory handled = true; printf_P(PSTR("FREE %u\n\r"),freeMemory()); break; } return handled; }
/* * === FUNCTION ====================================================================== * Name: ConvPoolLayer::flip_conv2d * Description: This function is used for single input 2d-image-convolution with a single kernels, in 'valid' mode. Strictly this is convolution * Arguments: map_input: input image to be convolved * kernel: convolution kernel * map_conved: convolved map * ===================================================================================== */ void ConvPoolLayer::flip_conv2d(const MatrixXd& map_input, const MatrixXd& kernel, MatrixXd& map_conved) { map_conved.resize(map_input.rows() + 1 - kernel.rows(), map_input.cols() + 1 - kernel.cols()); conv2d(map_input, kernel.reverse(), map_conved); } /* ----- end of function ConvPoolLayer::flip_conv2d ----- */
// Software Guide : BeginLatex // \vspace{0.5cm} // \Large{Main function} \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int main(int argc, char *argv[]) { // Software Guide : EndCodeSnippet if (argc != 4) { printf("Usage: %s input_image threshold padding_method\n", argv[0]); } else { // Execution time: double start = (double)clock(); // Load input image (using iio) // Software Guide : BeginLatex // Load input image (using \textit{iio}): \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int w, h, pixeldim; float *im_orig = iio_read_image_float_vec(argv[1], &w, &h, &pixeldim); // Software Guide : EndCodeSnippet fprintf(stderr, "Input image loaded:\t %dx%d image with %d channel(s).\n", w, h, pixeldim); // Grayscale conversion (if necessary) // Software Guide : BeginLatex // Grayscale conversion (if necessary): explained in \ref{sec:grayscale}. \\ \\ // Software Guide : EndLatex double *im = malloc(w*h*sizeof(double)); if (im == NULL){ fprintf(stderr, "Out of memory...\n"); exit(EXIT_FAILURE); } // allocate memory for the grayscale image <im>, output of the grayscale conversion // and correct allocation check. int z; // <z> is just an integer used as array index. int zmax = w*h; // number of elements of <im> if (pixeldim==3){ // if the image is color (RGB, three channels)... for(z=0;z<zmax;z++){ // for each pixel in the image <im>, calculate the gray // value according to the expression: // I = ( 6968*R + 23434*G + 2366*B ) / 32768. im[z] = (double)(6968*im_orig[3*z] + 23434*im_orig[3*z + 1] + 2366*im_orig[3*z + 2])/32768; } fprintf(stderr, "images converted to grayscale\n"); } else { // the image was originally grayscale... for(z=0;z<zmax;z++){ im[z] = (double)im_orig[z]; // only assign the value of im_orig to im, casting to double. } fprintf(stderr, "images are already in grayscale\n"); } // Define operators: // Software Guide : BeginLatex // Define the normalized Roberts, Prewitt and Sobel operators: \\ // (We use $3\times 3$ operators) // \begin{itemize} // \item Roberts: // $$ // R_1 = \begin{bmatrix} -1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{bmatrix} // $$ // $$ // R_2 = \begin{bmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix} // $$ // \item Prewitt: // $$ // P_1 = \begin{bmatrix} \frac{-1}{6} & \frac{-1}{6} & \frac{-1}{6} \\ 0 & 0 & 0 \\ \frac{1}{6} & \frac{1}{6} & \frac{1}{6} \end{bmatrix} // $$ // $$ // P_2 = \begin{bmatrix} \frac{-1}{6} & 0 & \frac{1}{6} \\ \frac{-1}{6} & 0 & \frac{1}{6} \\ \frac{-1}{6} & 0 & \frac{1}{6} \end{bmatrix} // $$ // \item Sobel: // $$ // S_1 = \begin{bmatrix} \frac{-1}{8} & \frac{-1}{4} & \frac{-1}{8} \\ 0 & 0 & 0 \\ \frac{1}{8} & \frac{1}{4} & \frac{1}{8} \end{bmatrix} // $$ // $$ // S_2 = \begin{bmatrix} \frac{-1}{8} & 0 & \frac{1}{8} \\ \frac{-1}{4} & 0 & \frac{1}{4} \\ \frac{-1}{8} & 0 & \frac{1}{8} \end{bmatrix} // $$ // \end{itemize} // Software Guide : EndLatex // Software Guide : BeginCodeSnippet double roberts_1[9] = {-1, 0, 0, 0, 1, 0, 0, 0, 0}; // ROBERTS double roberts_2[9] = { 0,-1, 0, 1, 0, 0, 0, 0, 0}; // OPERATORS //--------------------------------------------------------------------------------- double prewitt_1[9] = {-1,-1,-1, 0, 0, 0, 1, 1, 1}; // PREWITT double prewitt_2[9] = {-1, 0, 1,-1, 0, 1,-1, 0, 1}; // OPERATORS //--------------------------------------------------------------------------------- double sobel_1[9] = {-1,-2,-1, 0, 0, 0, 1, 2, 1}; // SOBEL double sobel_2[9] = {-1, 0, 1,-2, 0, 2,-1, 0, 1}; // OPERATORS //--------------------------------------------------------------------------------- for (z=0;z<9;z++) { // NORMALIZATION //roberts_1[z] /= 1; //roberts_2[z] /= 1; prewitt_1[z] /= 6; prewitt_2[z] /= 6; sobel_1[z] /= 8; sobel_2[z] /= 8; } // Software Guide : EndCodeSnippet // Convolve images: // Software Guide : BeginLatex // The input image is convolved with the defined operatos, using the \texttt{conv2d} function in \texttt{2dconvolution.c}: // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int padding_method = atoi(argv[3]); double *im_r1 = conv2d(im, w, h, roberts_1, 3, padding_method); double *im_r2 = conv2d(im, w, h, roberts_2, 3, padding_method); double *im_p1 = conv2d(im, w, h, prewitt_1, 3, padding_method); double *im_p2 = conv2d(im, w, h, prewitt_2, 3, padding_method); double *im_s1 = conv2d(im, w, h, sobel_1, 3, padding_method); double *im_s2 = conv2d(im, w, h, sobel_2, 3, padding_method); // Software Guide : EndCodeSnippet // Allocate memory for final images: // Software Guide : BeginLatex // Allocate memory for final images: // Software Guide : EndLatex // Software Guide : BeginCodeSnippet float *im_roberts = malloc(w*h*sizeof(float)); float *im_prewitt = malloc(w*h*sizeof(float)); float *im_sobel = malloc(w*h*sizeof(float)); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // For each method, two images are obtained (one for each operator). Then the gradient magnitude image is constructed using $M=\sqrt{g_x^2+g_y^2}$. \\ // Also the absolute maximum value of the constructed images is computed, for each method. \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet int i,j, fila, col; double max_r = 0; double max_p = 0; double max_s = 0; int imax = w*h; for (i=0;i<imax;i++){ fila = (int)(i/w); col = i - w*fila + 1; fila += 1; j = col + (w+2)*fila; // Max in each case im_roberts[i] = sqrt(im_r1[j]*im_r1[j] + im_r2[j]*im_r2[j]); im_prewitt[i] = sqrt(im_p1[j]*im_p1[j] + im_p2[j]*im_p2[j]); im_sobel[i] = sqrt(im_s1[j]*im_s1[j] + im_s2[j]*im_s2[j]); // Absolute max max_r = MAX(max_r,im_roberts[i]); max_p = MAX(max_p,im_prewitt[i]); max_s = MAX(max_s,im_sobel[i]); } // Software Guide : EndCodeSnippet // Thresholding // Software Guide : BeginLatex // Thresholded images of each method are created, using the THRESHOLD macro: \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet float th = atof(argv[2]); for (i=0;i<imax;i++){ im_roberts[i] = THRESHOLD(im_roberts[i],th*max_r); im_prewitt[i] = THRESHOLD(im_prewitt[i],th*max_p); im_sobel[i] = THRESHOLD(im_sobel[i],th*max_s); } // Software Guide : EndCodeSnippet // Save outout images // Software Guide : BeginLatex // Save output image (using \textit{iio}): \\ // Software Guide : EndLatex // Software Guide : BeginCodeSnippet iio_save_image_float_vec("roberts.png", im_roberts, w, h, 1); iio_save_image_float_vec("prewitt.png", im_prewitt, w, h, 1); iio_save_image_float_vec("sobel.png", im_sobel, w, h, 1); // Software Guide : EndCodeSnippet fprintf(stderr, "Roberts image saved to roberts.png.\n"); fprintf(stderr, "Prewitt image saved to prewitt.png.\n"); fprintf(stderr, "Sobel image saved to sobel.png.\n"); // Free memory: free(im_orig); free(im); free(im_r1); free(im_r2); free(im_p1); free(im_p2); free(im_s1); free(im_s2); free(im_roberts); free(im_prewitt); free(im_sobel); fprintf(stderr, "Edge detection algorithms based on first derivative computation done.\n"); // Execution time: double finish = (double)clock(); double exectime = (finish - start)/CLOCKS_PER_SEC; fprintf(stderr, "execution time: %1.3f s.\n", exectime); return 0; } // else (argc) } // end of the program
// Haralick edge detector // inputs: // float *input - pointer to input image // int w, int h - width and height of input image // float rhozero - threshold // int padding_method - padding method for convolution // output: // float * - pointer to output image float *edges_haralick(float *im, int w, int h, float rhozero, int padding_method) { // Haralick's masks for computing k1 to k10 // New masks calculated by 2-d fitting using LS, with the function // f(x,y) = k1 + k2*x + k3*y + k4*x^2 + k5*xy // + k6*y^2 + k7*x^3 + k8*x^2y + k9*xy^2 + k10*y^3 float mask[10][25] = { { 425, 275, 225, 275, 425, 275, 125, 75, 125, 275, 225, 75, 25, 75, 225, 275, 125, 75, 125, 275, 425, 275, 225, 275, 425}, { -2260, -620, 0, 620, 2260, -1660, -320, 0, 320, 1660, -1460, -220, 0, 220, 1460, -1660, -320, 0, 320, 1660, -2260, -620, 0, 620, 2260}, { 2260, 1660, 1460, 1660, 2260, 620, 320, 220, 320, 620, 0, 0, 0, 0, 0, -620, -320, -220, -320, -620, -2260, -1660,-1460,-1660,-2260}, { 1130, 620, 450, 620, 1130, 830, 320, 150, 320, 830, 730, 220, 50, 220, 730, 830, 320, 150, 320, 830, 1130, 620, 450, 620, 1130}, { -400, -200, 0, 200, 400, -200, -100, 0, 100, 200, 0, 0, 0, 0, 0, 200, 100, 0, -100, -200, 400, 200, 0, -200, -400}, { 1130, 830, 730, 830, 1130, 620, 320, 220, 320, 620, 450, 150, 50, 150, 450, 620, 320, 220, 320, 620, 1130, 830, 730, 830, 1130}, { -8260, -2180, 0, 2180, 8260, -6220, -1160, 0, 1160, 6220, -5540, -820, 0, 820, 5540, -6220, -1160, 0, 1160, 6220, -8260, -2180, 0, 2180, 8260}, { 5640, 3600, 2920, 3600, 5640, 1800, 780, 440, 780, 1800, 0, 0, 0, 0, 0, -1800, -780, -440, -780,-1800, -5640, -3600,-2920,-3600,-5640}, { -5640, -1800, 0, 1800, 5640, -3600, -780, 0, 780, 3600, -2920, -440, 0, 440, 2920, -3600, -780, 0, 780, 3600, -5640, -1800, 0, 1800, 5640}, { 8260, 6220, 5540, 6220, 8260, 2180, 1160, 820, 1160, 2180, 0, 0, 0, 0, 0, -2180, -1160, -820,-1160,-2180, -8260, -6220, -5540,-6220,-8260 } }; // apply the masks operators, this will lead to coefficients k1 to k10 float *aux[10]; for(int i=0; i<10; i++) { aux[i] = conv2d(im, w, h, mask[i], 5, padding_method); } float eps=1e-16; // compute Haralick edges float *edges = xmalloc(w*h*sizeof(float)); // get memory for output for(int i=0; i<w; i++) { for(int j=0; j<h; j++) { // aux is (w+4)x(h+4) and there is an offset of (2,2) // k1 is not used float k2 = aux[1][i+2 + (j+2)*(w+4)]; float k3 = aux[2][i+2 + (j+2)*(w+4)]; float k4 = aux[3][i+2 + (j+2)*(w+4)]; float k5 = aux[4][i+2 + (j+2)*(w+4)]; float k6 = aux[5][i+2 + (j+2)*(w+4)]; float k7 = aux[6][i+2 + (j+2)*(w+4)]; float k8 = aux[7][i+2 + (j+2)*(w+4)]; float k9 = aux[8][i+2 + (j+2)*(w+4)]; float k10 = aux[9][i+2 + (j+2)*(w+4)]; float sintheta = -k2 / sqrt(k2*k2 + k3*k3+eps); float costheta = -k3 / sqrt(k2*k2 + k3*k3+eps); float C1 = k2 * sintheta + k3 * costheta; float C2 = k4 * sintheta * sintheta + k5 * sintheta * costheta + k6 * costheta * costheta; float C3 = k7 * sintheta * sintheta * sintheta + k8 * sintheta * sintheta * costheta + k9 * sintheta * costheta * costheta + k10 * costheta * costheta * costheta; int cond1=fabs( C2 / (3.0 * C3+eps)) < rhozero; int cond2=C3 < 0.0; /* this condition is implicit, does not need to be checked, but we do to provide extra safety. */ int cond3=C2 > 0.0; //this one does not need to be imposed by construction, see paper. //int cond4=fabs(C1-C2*C2/C3/3) > 0.0; if( cond1 && cond2 && cond3) { edges[i+j*w] = 255.0; } else { edges[i+j*w] = 0.0; } } } // free memory for(int i=0; i<10; i++) { free(aux[i]); } return edges; }