Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

Commit

Permalink
for region management, convert grayscale image to binary image
Browse files Browse the repository at this point in the history
using otsu algorithm and extract edge from binary image.
some test code in WireMatching.cc
  • Loading branch information
xorrhks0216 committed Jun 23, 2013
1 parent 8407b0e commit d452331
Show file tree
Hide file tree
Showing 4 changed files with 274 additions and 0 deletions.
172 changes: 172 additions & 0 deletions lib/BinaryLineDetection.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/* -*-c++-*-
This file is part of the IC reverse engineering tool degate.
Copyright 2008, 2009, 2010 by Martin Schobert
Copyright 2013 by Taekgwan Kim
Degate is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
Degate is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with degate. If not, see <http://www.gnu.org/licenses/>.
*/

#include <BinaryLineDetection.h>
#include <Otsu.h>
#include <IPCopy.h>
#include <IPMedianFilter.h>
#include <IPNormalize.h>
#include <IPConvolve.h>
#include <IPThresholding.h>

#include <ImageManipulation.h>
#include <IPImageWriter.h>

using namespace degate;

BinaryLineDetection::BinaryLineDetection(unsigned int _min_x, unsigned int _max_x,
unsigned int _min_y, unsigned int _max_y,
unsigned int _wire_diameter,
unsigned int _median_filter_width,
unsigned int _blur_kernel_size,
double _sigma) :
min_x(_min_x),
max_x(_max_x),
min_y(_min_y),
max_y(_max_y),
wire_diameter(_wire_diameter),
median_filter_width(_median_filter_width),
blur_kernel_size(_blur_kernel_size),
border(_blur_kernel_size >> 1),
sigma(_sigma),
has_path(false) {

setup_pipe();
}

BinaryLineDetection::~BinaryLineDetection() {}

TileImage_GS_DOUBLE_shptr BinaryLineDetection::run(ImageBase_shptr img_in,
TileImage_GS_DOUBLE_shptr probability_map,
std::string const& directory) {

set_directory(directory);
grayImage = std::dynamic_pointer_cast<TileImage_GS_DOUBLE>(pipe.run(img_in));
binImage = gs_to_binary(grayImage);
regionImage = binary_to_region(binImage);

return regionImage;
}

void BinaryLineDetection::setup_pipe() {

debug(TM, "will extract background image (%d, %d) (%d, %d)", min_x, min_y, max_x, max_y);
std::shared_ptr<IPCopy<TileImage_RGBA, TileImage_GS_DOUBLE> > copy_rgba_to_gs
(new IPCopy<TileImage_RGBA, TileImage_GS_DOUBLE>(min_x, max_x, min_y, max_y));

pipe.add(copy_rgba_to_gs);

if(median_filter_width > 0) {
std::shared_ptr<IPMedianFilter<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE> > median_filter
(new IPMedianFilter<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE>(median_filter_width));

pipe.add(median_filter);
}

std::shared_ptr<IPNormalize<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE> > normalizer
(new IPNormalize<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE>(0, 255) );

pipe.add(normalizer);

if(blur_kernel_size > 0) {
std::shared_ptr<GaussianBlur>
GaussianB(new GaussianBlur(blur_kernel_size, blur_kernel_size, sigma));

GaussianB->print();
std::shared_ptr<IPConvolve<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE> > gaussian_blur
(new IPConvolve<TileImage_GS_DOUBLE, TileImage_GS_DOUBLE>(GaussianB) );

pipe.add(gaussian_blur);
}

}

unsigned int BinaryLineDetection::get_width() const {
return max_x - min_x;
}

unsigned int BinaryLineDetection::get_height() const {
return max_y - min_y;
}

unsigned int BinaryLineDetection::get_border() const {
return border;
}

std::string BinaryLineDetection::get_directory() const {
return directory;
}

bool BinaryLineDetection::has_directory() const {
return has_path;
}

void BinaryLineDetection::set_directory(std::string const& path) {
directory = path;
has_path = true;
}

TileImage_GS_DOUBLE_shptr BinaryLineDetection::gs_to_binary(TileImage_GS_DOUBLE_shptr gray) {

Otsu o;
TileImage_GS_DOUBLE_shptr binary_image(new TileImage_GS_DOUBLE(get_width(), get_height()));
double otsu_threshold;

o.run(gray);
otsu_threshold = o.get_otsu_threshold();

for(unsigned int y = border; y < get_height() - border- 1; y++) {
for(unsigned int x = border; x < get_width() - border- 1; x++) {
if(gray->get_pixel(x, y) < otsu_threshold)
binary_image->set_pixel(x, y, 0);
else
binary_image->set_pixel(x, y, 1);
}
}

return binary_image;

}

TileImage_GS_DOUBLE_shptr BinaryLineDetection::binary_to_region(TileImage_GS_DOUBLE_shptr binary) {

TileImage_GS_DOUBLE_shptr region(new TileImage_GS_DOUBLE(get_width(), get_height()));
unsigned int temp_y, temp_x_start, temp_x_end;

for(unsigned int y = border; y < get_height() - border - 1; y++) {
for(unsigned int x = border; x < get_width() - border - 1; x++) {
if(binary->get_pixel(x, y) == 0) continue;
else if(binary->get_pixel(x, y) == 1) {
temp_y = y;
temp_x_start = x;
while(binary->get_pixel(++x, y) == 1) {
if(x == get_width() - border) break;
}
temp_x_end = x - 1;
}
region->set_pixel(temp_x_start, temp_y, 1);
region->set_pixel(temp_x_end, temp_y, 1);
}
}

return region;
}
88 changes: 88 additions & 0 deletions lib/BinaryLineDetection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* -*-c++-*-
This file is part of the IC reverse engineering tool degate.
Copyright 2013 by Taekgwan Kim
Degate is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
Degate is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with degate. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __BINARYLINEDETECTION_H__
#define __BINARYLINEDETECTION_H__

#include <Image.h>
#include <IPPipe.h>

namespace degate {

class BinaryLineDetection {

private:

IPPipe pipe;

unsigned int min_x, max_x, min_y, max_y;
unsigned int wire_diameter;
unsigned int median_filter_width;

unsigned int blur_kernel_size, border;
double sigma;
bool has_path;

TileImage_GS_DOUBLE_shptr grayImage;
TileImage_GS_DOUBLE_shptr binImage;
TileImage_GS_DOUBLE_shptr regionImage;

std::string directory; // path for storing debug images

private:

public:

void setup_pipe();

unsigned int get_width() const;
unsigned int get_height() const;
unsigned int get_border() const;

std::string get_directory() const;

bool has_directory() const;

void set_directory(std::string const& path);

TileImage_GS_DOUBLE_shptr gs_to_binary(TileImage_GS_DOUBLE_shptr gray);
TileImage_GS_DOUBLE_shptr binary_to_region(TileImage_GS_DOUBLE_shptr binary);

public:

BinaryLineDetection(unsigned int min_x, unsigned int max_x,
unsigned int min_y, unsigned int max_y,
unsigned int wire_diameter,
unsigned int median_filter_width = 3,
unsigned int blur_kernel_size = 10,
double sigma = 0.5);

~BinaryLineDetection();

TileImage_GS_DOUBLE_shptr run(ImageBase_shptr img_in,
TileImage_GS_DOUBLE_shptr probability_map,
std::string const& directory);

};

}

#endif
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ set(SOURCES
EdgeDetection.cc
CannyEdgeDetection.cc
ZeroCrossingEdgeDetection.cc
BinaryLineDetection.cc
WireMatching.cc
ViaMatching.cc
TemplateMatching.cc
Expand Down
13 changes: 13 additions & 0 deletions lib/WireMatching.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <WireMatching.h>
#include <ZeroCrossingEdgeDetection.h>
#include <BinaryLineDetection.h>
#include <BoundingBox.h>
#include <LineSegmentExtraction.h>
#include <MedianFilter.h>
Expand Down Expand Up @@ -90,6 +91,18 @@ void WireMatching::run() {
TileImage_GS_DOUBLE_shptr i = ed.run(img, TileImage_GS_DOUBLE_shptr(), "/tmp");
assert(i != NULL);

BinaryLineDetection test(bounding_box.get_min_x(),
bounding_box.get_max_x(),
bounding_box.get_min_y(),
bounding_box.get_max_y(),
wire_diameter,
median_filter_width,
sigma > 0 ? 10 : 0,
sigma);
TileImage_GS_DOUBLE_shptr j = test.run(img, TileImage_GS_DOUBLE_shptr(), "/tmp");
assert(j != NULL);
save_normalized_image<TileImage_GS_DOUBLE>(join_pathes(test.get_directory(), "line.tif"), j);

LineSegmentExtraction<TileImage_GS_DOUBLE> extraction(i, wire_diameter/2, 2, ed.get_border());
LineSegmentMap_shptr line_segments = extraction.run();
assert(line_segments != NULL);
Expand Down

0 comments on commit d452331

Please sign in to comment.