IonDetector::result_type IonDetector::blob_detector( const image_type& img ) { Kernel logs[3]; float sigmas[3]; logs[0] = Kernel::LoG( 4, 0.6 ); sigmas[0] = 0.85; logs[1] = Kernel::LoG( 6, 1.0 ); sigmas[1] = 1.0; logs[2] = Kernel::LoG( 20, 5.0 ); sigmas[2] = 2.; image_type img_result( img.extents ); result_type results; const size_t hsize = 2000; std::vector< size_t > histogram( hsize, 0 ); size_t g = 2; logs[g].apply_kernel( img, img_result ); save_file( "log.fits", img_result ); float img_max = *std::max_element( img_result.ptr(), img_result.ptr() + img.num_elements() ); for( float* iter = img_result.ptr(); iter != img_result.ptr() + img.num_elements(); ++iter ) { int p = (size_t)( ( *iter + img_max ) / 2 / img_max * hsize ); if( p >= (int)hsize ) p = hsize-1; if( p < 0 ) p = 0; histogram[ p ] ++; } size_t nelems = 0, counter = hsize-1; while( nelems < (size_t)blob_threshold ) nelems += histogram[ counter-- ]; float thresh = (float)counter / hsize * img_max - img_max / 2.; for( image_type::index i = 12; i < img.extents.first-12; ++i ) for( image_type::index j = 12; j < img.extents.second-12; ++j ) { if( img_result( i, j ) > thresh && img_result( i, j ) > img_result( i+1, j ) && img_result( i, j ) > img_result( i-1, j ) && img_result( i, j ) > img_result( i, j+1 ) && img_result( i, j ) > img_result( i, j-1 ) && img_result( i, j ) > img_result( i+1, j+1 ) && img_result( i, j ) > img_result( i+1, j-1 ) && img_result( i, j ) > img_result( i-1, j+1 ) && img_result( i, j ) > img_result( i-1, j-1 ) ) { results.push_back( IonData( i, j, sigmas[g] ) ); } } return results; }
IonDetector::result_type IonDetector::hough_transform( image_type& edges ) { const unsigned short num_radii = 4; std::vector< unsigned short > hough( edges.num_elements()*num_radii, 0 ); for( size_t r = 2; r < 6; ++r ) for( image_type::index i = r+1; i<edges.extents.first-r-1; ++i ) for( image_type::index j = r+1; j<edges.extents.second-r-1; ++j ) { if( edges( i, j ) ) { for( float theta = 0.; theta < 6.3; theta += 1. / r ) { size_t x = (size_t)( i + (float)r*cos( theta ) + 0.5f); size_t y = (size_t)( j + (float)r*sin( theta ) + 0.5f); hough[ (r-2)*edges.num_elements() + y*edges.extents.first + x ]++; } } } result_type results; for( size_t r = 5; r >= 2; --r ) for( image_type::index i = 8; i < edges.extents.first-8; ++i ) for( image_type::index j = 8; j < edges.extents.second-8; ++j ) { size_t index = (r-2)*edges.num_elements() + j*edges.extents.first + i; const unsigned short value = hough[index]; if( value > (size_t)(hough_threshold * r) ) { size_t h = 0; for( ; h < results.size(); ++h ) { size_t xsq = (i - results[h].x)*(i - results[h].x); size_t ysq = (j - results[h].y)*(j - results[h].y); if( xsq + ysq < 36 ) break; } if( h != results.size() ) continue; if( hough[index + edges.extents.first] > value ) continue; if( hough[index - edges.extents.first] > value ) continue; if( hough[index - 1] > value ) continue; if( hough[index + 1] > value ) continue; results.push_back( IonData( i, j, r ) ); std::cout<< "Circle " << i << " " << j << " " << r << std::endl; std::cout<< value << std::endl; } } return results; }
void save_file( const std::string& filename, const image_type& img ) { fitsfile* f; int status = 0; std::string fname = "!" + filename; fits_create_file( &f, fname.c_str(), &status ); long dims[2]; dims[0] = img.extents.first; dims[1] = img.extents.second; typedef CFitsIOTypeMap< image_type::element > map; fits_create_img( f, map::image_type, 2, dims, &status ); fits_write_img( f, map::type, 1, img.num_elements(), (void*)img.ptr(), &status ); fits_close_file( f, &status ); if( status ) { fits_report_error( stderr, status ); } }