-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 68345d4
Showing
7 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
imgs/* | ||
obj/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
CC=gcc | ||
CPP=g++ | ||
LD=g++ | ||
|
||
CFLAGS=-c -Wall -O2 -I/u/yli/include/ -fopenmp | ||
LDFLAGS=-O2 -lopencv_imgproc -lopencv_core -lopencv_highgui -lopencv_video -fopenmp -L/u/yli/lib/ | ||
EXEC = rgmRect | ||
|
||
OBJ_DIR=obj | ||
SRC_DIR=src | ||
|
||
C_OBJECTS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(wildcard $(SRC_DIR)/*.c)) | ||
CC_OBJECTS = $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/%.o,$(wildcard $(SRC_DIR)/*.cc)) | ||
CPP_OBJECTS = $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(wildcard $(SRC_DIR)/*.cpp)) | ||
|
||
$(EXEC): $(C_OBJECTS) $(CC_OBJECTS) $(CPP_OBJECTS) | ||
$(LD) -o $@ $^ $(LDFLAGS) | ||
|
||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | ||
$(CC) -c -o $@ $< $(CFLAGS) | ||
|
||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc | ||
$(CC) -c -o $@ $< $(CFLAGS) | ||
|
||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | ||
$(CPP) -c -o $@ $< $(CFLAGS) | ||
|
||
.PHONY: clean | ||
|
||
clean: | ||
rm -f $(CC_OBJECTS) $(C_OBJECTS) $(CPP_OBJECTS) $(EXEC) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
Upright Rectangular Detection | ||
-------------- | ||
|
||
Author: Yuncheng Li | ||
[email protected] | ||
|
||
University of Rochester | ||
Department of Computer Science | ||
727 Computer Studies Bldg | ||
Rochester, NY 14623 | ||
USA | ||
|
||
*********** Assumption ******** | ||
* Only one upright black rectangle appeared in the image | ||
* This assumption can be removed, if necessary. | ||
|
||
*********** Parameters ******** | ||
|
||
Configurable in the config.xml, the default value works with provided data | ||
|
||
brightness_thresh: definition of black (the larger this value, any pixel with brightness_thresh less than this value will be treated as black) | ||
width_thresh: minimum rectangle width | ||
height_thresh: minimum rectangle height | ||
thick_thresh: maximum thickness of the rectangle (thickness means the width of each edge) | ||
area_ratio: a value not easy to describe. valid value is 1.00 ~ 2.00. The larger this value, the higher false alarm rate is. (false alarm means there is no upright black rectangle, but this program report one) | ||
|
||
********* How to run **** | ||
* single run | ||
./rgmRect img-filename(full path) | ||
* check test.sh to see how to do multi-run | ||
* $ make # to build | ||
* add /u/yli/lib/ into LD_LIBRARY_PATH environment variable to make it run | ||
* The detected rectangle will be output into standard output | ||
|
||
******** LICENSING TERMS ******************* | ||
|
||
This code is granted free of charge for non-commercial research and education purpose. However, commercial uses can be granted by obtaining a license from the author. | ||
|
||
1, All code shall be acknowledged in any scientific results produced using the provided code. | ||
|
||
2, The author of the code base shall be informed about the publication. | ||
|
||
3, The software or any derivative software must not be distributed without prior permission of the author. | ||
|
||
4, By using any of the codes in the code, you agree to this LICENSING terms | ||
|
||
|
||
******** Disclaimer of Warranty (GPL Term)*********** | ||
|
||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0"?> | ||
<opencv_storage> | ||
<params> | ||
<brightness_thresh>50</brightness_thresh> | ||
<width_thresh>10</width_thresh> | ||
<height_thresh>10</height_thresh> | ||
<thick_thresh>5</thick_thresh> | ||
<area_ratio>1.5000000000000000e+00</area_ratio></params> | ||
</opencv_storage> |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/** | ||
* @author Yuncheng Li (raingomm[AT]gmail.com) | ||
* @version 2013/04/12 | ||
*/ | ||
|
||
|
||
#include <opencv2/core/core.hpp> | ||
#include <opencv2/imgproc/imgproc.hpp> | ||
#include <opencv2/highgui/highgui.hpp> | ||
|
||
#include <iostream> | ||
|
||
using namespace std; | ||
using namespace cv; | ||
|
||
struct params { | ||
int thresh, l1, l2, disk0; | ||
double ratio; | ||
|
||
params() | ||
{ | ||
thresh = 50; | ||
l1 = 10; | ||
l2 = 10; | ||
disk0 = 5; | ||
ratio = 1.5; | ||
} | ||
|
||
void write(FileStorage &fs) const | ||
{ | ||
fs << "{" << "brightness_thresh" << thresh | ||
<< "width_thresh" << l1 | ||
<< "height_thresh" << l2 | ||
<< "thick_thresh" << disk0 | ||
<< "area_ratio" << ratio | ||
<< "}"; | ||
} | ||
|
||
void read(const FileNode &node) | ||
{ | ||
thresh = (int)node["brightness_thresh"]; | ||
l1 = (int)node["width_thresh"]; | ||
l2 = (int)node["height_thresh"]; | ||
disk0 = (int)node["thick_thresh"]; | ||
ratio = (double)node["area_ratio"]; | ||
} | ||
}; | ||
|
||
inline void write(FileStorage& fs, const std::string&, const params& x) | ||
{ | ||
x.write(fs); | ||
} | ||
|
||
inline void read(const FileNode& node, params &x, const params & default_value = params()) | ||
{ | ||
if(node.empty()) | ||
x = default_value; | ||
else | ||
x.read(node); | ||
} | ||
|
||
Mat filtering(const Mat &_bgrImg, const params ¶m) | ||
{ | ||
Mat se1 = getStructuringElement( MORPH_RECT, Size( param.l1, 1 ), Point( param.l1 >> 1, 0) ); | ||
Mat se2 = getStructuringElement( MORPH_RECT, Size( 1, param.l2), Point(0, param.l2 >> 1) ); | ||
Mat se3 = getStructuringElement( MORPH_RECT, Size( param.disk0, param.disk0), Point(param.disk0 >> 1, param.disk0 >> 1) ); | ||
|
||
vector<Mat> bgrSplit; | ||
split(_bgrImg, bgrSplit); | ||
Mat mask = Mat::ones(_bgrImg.size(), CV_8UC1); | ||
|
||
for (int i = 0; i < 3; i++) { | ||
Mat threshed; | ||
threshold(bgrSplit[i], threshed, param.thresh, 1,THRESH_BINARY_INV); | ||
bitwise_and(threshed, mask, mask); | ||
} | ||
|
||
Mat mask1; | ||
Mat mask2; | ||
Mat mask3; | ||
|
||
morphologyEx(mask, mask1, MORPH_OPEN, se1); | ||
morphologyEx(mask, mask2, MORPH_OPEN, se2); | ||
morphologyEx(mask, mask3, MORPH_OPEN, se3); | ||
|
||
//imwrite("mask1.bmp", mask1 * 255); | ||
//imwrite("mask2.bmp", mask2 * 255); | ||
//imwrite("mask3.bmp", mask3 * 255); | ||
|
||
bitwise_or(mask1, mask2, mask); | ||
bitwise_not(mask3, mask3); | ||
bitwise_and(mask, mask3, mask); | ||
|
||
return mask; | ||
} | ||
|
||
static double upright(Point pt1, Point pt2) | ||
{ | ||
double dx = pt1.x - pt2.x; | ||
double dy = pt1.y - pt2.y; | ||
|
||
double maxd = std::min(fabs(dx), fabs(dy)); | ||
|
||
return maxd / sqrt(dx*dx + dy*dy); | ||
} | ||
|
||
static double angle( Point pt1, Point pt2, Point pt0 ) | ||
{ | ||
double dx1 = pt1.x - pt0.x; | ||
double dy1 = pt1.y - pt0.y; | ||
double dx2 = pt2.x - pt0.x; | ||
double dy2 = pt2.y - pt0.y; | ||
return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); | ||
} | ||
|
||
|
||
Rect detectRect(Mat &map, const params ¶m) | ||
{ | ||
vector<vector<Point> > contours; | ||
findContours(map, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); | ||
|
||
Rect bestRect; | ||
double bestRatio = std::numeric_limits<double>::max(); | ||
|
||
for (size_t i = 0; i < contours.size(); ++i) | ||
{ | ||
Rect tmp = boundingRect(contours[i]); | ||
|
||
double area1 = tmp.width * tmp.height; | ||
|
||
vector<Point> cvxhull; | ||
convexHull(contours[i], cvxhull); | ||
double area2 = contourArea(cvxhull); | ||
|
||
double ratio = area1 / (area2 + 1e-10); | ||
|
||
if (bestRatio > ratio) | ||
{ | ||
bestRect = tmp; | ||
bestRatio = ratio; | ||
} | ||
} | ||
|
||
if (bestRatio < param.ratio) | ||
return bestRect; | ||
else | ||
return Rect(); | ||
} | ||
|
||
int main(int argc, const char *argv[]) | ||
{ | ||
|
||
if (argc < 2) | ||
{ | ||
cerr << argv[0] << " img-filename" << endl; | ||
return 0; | ||
} | ||
|
||
Mat img = imread(argv[1]); | ||
|
||
if (img.empty()) | ||
{ | ||
cerr << argv[1] << " is not a valid image file" << endl; | ||
return 0; | ||
} | ||
|
||
params m_param; | ||
FileStorage fs("config.xml", FileStorage::READ); | ||
fs["params"] >> m_param; | ||
|
||
Mat I = filtering(img, m_param); | ||
|
||
Rect rect = detectRect(I, m_param); | ||
|
||
if (rect.width != 0 && rect.height != 0) | ||
cout << rect.x << ' ' << rect.y << ' ' << rect.width << ' ' << rect.height << endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/bash | ||
|
||
for img in imgs/*.jpg | ||
do | ||
echo "$img" | ||
./rgmRect "$img" | ||
done |