|
degate 0.1.1
|
00001 /* -*-c++-*- 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #include <ZeroCrossingEdgeDetection.h> 00023 #include <MorphologicalFilter.h> 00024 00025 using namespace degate; 00026 00027 ZeroCrossingEdgeDetection::ZeroCrossingEdgeDetection(unsigned int min_x, unsigned int max_x, 00028 unsigned int min_y, unsigned int max_y, 00029 unsigned int median_filter_width, 00030 unsigned int blur_kernel_size, 00031 double sigma, 00032 unsigned int _min_d, 00033 unsigned int _max_d, 00034 double _edge_threshold, 00035 double _zero_threshold) : 00036 EdgeDetection(min_x, max_x, min_y, max_y, median_filter_width, blur_kernel_size, sigma), 00037 min_d(_min_d), 00038 max_d(_max_d), 00039 edge_threshold(_edge_threshold), 00040 zero_threshold(_zero_threshold) { 00041 } 00042 00043 TileImage_GS_DOUBLE_shptr 00044 ZeroCrossingEdgeDetection::run(ImageBase_shptr img_in, 00045 TileImage_GS_DOUBLE_shptr probability_map) { 00046 00047 run_edge_detection(img_in); 00048 TileImage_GS_DOUBLE_shptr edge_image = get_edge_image(probability_map); 00049 //TileImage_GS_DOUBLE_shptr edge_magnitude_image = get_edge_magnitude_image(probability_map); 00050 00051 TileImage_GS_DOUBLE_shptr zero_cross_img = 00052 analyze_edge_image(edge_image, probability_map, min_d, max_d); 00053 00054 TileImage_GS_DOUBLE_shptr zero_cross_img2(new TileImage_GS_DOUBLE(get_width(), get_height())); 00055 00056 morphological_close<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE> 00057 (zero_cross_img2, zero_cross_img, 3, 1, 3); 00058 00059 thinning<TileImage_GS_DOUBLE>(zero_cross_img2); 00060 00061 return zero_cross_img2; 00062 } 00063 00064 TileImage_GS_DOUBLE_shptr ZeroCrossingEdgeDetection::run(ImageBase_shptr img_in, 00065 TileImage_GS_DOUBLE_shptr probability_map, 00066 std::string const& directory) { 00067 set_directory(directory); 00068 assert(img_in != NULL); 00069 TileImage_GS_DOUBLE_shptr zero_cross_img = run(img_in, probability_map); 00070 assert(zero_cross_img != NULL); 00071 00072 save_normalized_image<TileImage_GS_DOUBLE>(join_pathes(directory, "03_edge_zero_cross.tif"), 00073 zero_cross_img); 00074 00075 /* 00076 overlay_result(zero_cross_img, 00077 std::tr1::dynamic_pointer_cast<TileImage_GS_DOUBLE>(img_in), 00078 directory); 00079 */ 00080 return zero_cross_img; 00081 } 00082 00083 00084 bool ZeroCrossingEdgeDetection::trace(TileImage_GS_DOUBLE_shptr edge_image, 00085 int _x, int _y, 00086 int inc_x, int inc_y, 00087 int * start_x, int * stop_x, 00088 int * start_y, int * stop_y, 00089 double * mag, 00090 double edge_threshold, 00091 double zero_threshold, 00092 unsigned int min_d, unsigned int max_d) { 00093 00094 if(start_x == NULL || start_y == NULL || 00095 stop_x == NULL || stop_y == NULL || mag == NULL) return false; 00096 00097 enum STATE {BEFORE, POS_EDGE, NEG_EDGE, END}; 00098 STATE s = BEFORE; 00099 int x = _x, y = _y; 00100 double max_pix = 0, min_pix = 0; 00101 00102 while(s != END) { 00103 double p = edge_image->get_pixel(x, y); 00104 00105 if(s == BEFORE && p >= edge_threshold) { 00106 max_pix = p; 00107 *start_x = x; 00108 *start_y = y; 00109 s = POS_EDGE; 00110 } 00111 00112 else if(s == POS_EDGE) { 00113 if(p > max_pix) { 00114 *start_x = x; 00115 *start_y = y; 00116 max_pix = p; 00117 } 00118 if(p <= -edge_threshold) { 00119 *stop_x = x; 00120 *stop_y = y; 00121 min_pix = p; 00122 s = NEG_EDGE; 00123 } 00124 } 00125 else if(s == NEG_EDGE) { 00126 if(p < min_pix) { 00127 min_pix = p; 00128 *stop_x = x; 00129 *stop_y = y; 00130 } 00131 if(p >= 0 || 00132 x > *stop_x || y > *stop_y) { // that is at least one step beyond the maximum 00133 00134 unsigned int 00135 d_x = abs(*stop_x - *start_x), 00136 d_y = abs(*stop_y - *start_y); 00137 00138 00139 if( !((d_x > min_d && d_x < max_d) || 00140 (d_y > min_d && d_y < max_d))) return false; 00141 00142 s = END; // 00143 *mag = sqrt(pow(max_pix,2) + pow(min_pix, 2)); 00144 00145 double p_center = edge_image->get_pixel(*start_x + (*stop_x - *start_x)/2, 00146 *start_y + (*stop_y - *start_y)/2); 00147 00148 return fabs(p_center) < zero_threshold; 00149 00150 } 00151 } 00152 x += inc_x; 00153 y += inc_y; 00154 if(x >= edge_image->get_width() || 00155 y >= edge_image->get_height() || 00156 x == 0 || y == 0) s = END; 00157 } 00158 return false; 00159 } 00160 00161 00162 TileImage_GS_DOUBLE_shptr 00163 ZeroCrossingEdgeDetection::analyze_edge_image(TileImage_GS_DOUBLE_shptr edge_image, 00164 TileImage_GS_DOUBLE_shptr probability_map, 00165 unsigned int min_d, unsigned int max_d) { 00166 int start_x = 0, start_y = 0, stop_x = 0, stop_y = 0, x, y; 00167 double mag = 0; 00168 00169 normalize<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE>(edge_image, edge_image, -1, 1); 00170 00171 TileImage_GS_DOUBLE_shptr out_image(new TileImage_GS_DOUBLE(get_width(), get_height())); 00172 00173 for(y = get_border() ; y < edge_image->get_height() - get_border(); y++) { 00174 for(x = get_border(); x < edge_image->get_width() - get_border();) { 00175 00176 if(trace(edge_image, x, y, 1, 0, 00177 &start_x, &stop_x, &start_y, &stop_y, &mag, 00178 edge_threshold, zero_threshold, 00179 min_d, max_d)) { 00180 out_image->set_pixel(start_x + (stop_x - start_x)/2, y, mag); 00181 x += (stop_x > start_x + 1) ? stop_x - start_x - 1 : stop_x - start_x; 00182 } 00183 else x++; 00184 } 00185 } 00186 00187 for(x = get_border(); x < edge_image->get_width() - get_border(); x++) { 00188 for(y = get_border(); y < edge_image->get_height() - get_border();) { 00189 if(trace(edge_image, x, y, 0, 1, 00190 &start_x, &stop_x, &start_y, &stop_y, &mag, 00191 edge_threshold, zero_threshold, min_d, max_d)) { 00192 out_image->set_pixel(x, start_y + (stop_y - start_y)/2, mag); 00193 y += (stop_y > start_y + 1) ? stop_y - start_y -1 : stop_y - start_y; 00194 } 00195 else y++; 00196 } 00197 } 00198 00199 00200 /* 00201 for(x = get_border(); x < edge_image->get_width() - get_border(); x++) { 00202 for(y = get_border(); y < edge_image->get_height() - get_border(); y++) { 00203 if(trace(edge_image, x, y, 1, 1, 00204 &start_x, &stop_x, &start_y, &stop_y, &mag, 00205 edge_threshold, zero_threshold, sqrt(2*min_d*min_d), sqrt(2*max_d*max_d))) { 00206 int 00207 p_x = start_x + (stop_x - start_x)/2, 00208 p_y = start_y + (stop_y - start_y)/2; 00209 if(p_x >= 0 && p_y >= 0 && p_x < out_image->get_width() && p_y < out_image->get_height()) 00210 out_image->set_pixel(p_x, p_y, mag); 00211 } 00212 } 00213 } 00214 00215 00216 for(x = get_border(); x < edge_image->get_width() - get_border(); x++) { 00217 for(y = get_border(); y < edge_image->get_height() - get_border(); y++) { 00218 if(trace(edge_image, x, y, -1, 1, 00219 &start_x, &stop_x, &start_y, &stop_y, &mag, 00220 edge_threshold, zero_threshold, sqrt(2*min_d*min_d), sqrt(2*max_d*max_d))) { 00221 int 00222 p_x = start_x + (stop_x - start_x)/2, 00223 p_y = start_y + (stop_y - start_y)/2; 00224 if(p_x >= 0 && p_y >= 0 && p_x < out_image->get_width() && p_y < out_image->get_height()) 00225 out_image->set_pixel(p_x, p_y, mag); 00226 } 00227 } 00228 } 00229 */ 00230 00231 return out_image; 00232 } 00233 00234 void ZeroCrossingEdgeDetection::overlay_result(TileImage_GS_DOUBLE_shptr zc, 00235 TileImage_GS_DOUBLE_shptr bg, 00236 //TileImage_RGBA_shptr bg, 00237 std::string const& directory) const { 00238 00239 assert(bg != NULL && zc != NULL); 00240 00241 if(bg != NULL && zc != NULL) { 00242 for(unsigned int y = 0; y < get_height(); y++) 00243 for(unsigned int x = 0; x < get_width(); x++) { 00244 if(zc->get_pixel(x, y) > 0) 00245 bg->set_pixel(x, y, -1); 00246 } 00247 //save_image<TileImage_RGBA>(join_pathes(directory, "overlay.tif"), bg); 00248 save_normalized_image<TileImage_GS_DOUBLE>(join_pathes(directory, "overlay.tif"), bg); 00249 } 00250 } 00251
1.7.4