Repository: alyssaq/opencv
Branch: master
Commit: 76191301ee25
Files: 5
Total size: 12.1 KB
Directory structure:
gitextract_ishih8ed/
├── .gitignore
├── CMakeLists.txt
├── Makefile
├── README.md
└── squares.cpp
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
CMakeFiles
CMakeCache*
*.cmake
squares
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 2.8)
project( squares )
find_package( OpenCV REQUIRED )
add_executable( squares squares.cpp )
target_link_libraries( squares ${OpenCV_LIBS} )
================================================
FILE: Makefile
================================================
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 2.8
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
#=============================================================================
# Special targets provided by cmake.
# Disable implicit rules so canonical targets will work.
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
.SUFFIXES: .hpux_make_needs_suffix_list
# Suppress display of executed commands.
$(VERBOSE).SILENT:
# A target that is always out of date.
cmake_force:
.PHONY : cmake_force
#=============================================================================
# Set environment variables for the build.
# The shell in which to execute make rules.
SHELL = /bin/sh
# The CMake executable.
CMAKE_COMMAND = /opt/local/bin/cmake
# The command to remove a file.
RM = /opt/local/bin/cmake -E remove -f
# Escaping for special characters.
EQUALS = =
# The program to use to edit the cache.
CMAKE_EDIT_COMMAND = /opt/local/bin/ccmake
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /Users/alyssa/Documents/playground/C++/opencv
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /Users/alyssa/Documents/playground/C++/opencv
#=============================================================================
# Targets provided globally by CMake.
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
/opt/local/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache
# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
/opt/local/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast
# The main all target
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /Users/alyssa/Documents/playground/C++/opencv/CMakeFiles /Users/alyssa/Documents/playground/C++/opencv/CMakeFiles/progress.marks
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start /Users/alyssa/Documents/playground/C++/opencv/CMakeFiles 0
.PHONY : all
# The main clean target
clean:
$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean
# The main clean target
clean/fast: clean
.PHONY : clean/fast
# Prepare targets for installation.
preinstall: all
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall
# Prepare targets for installation.
preinstall/fast:
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast
# clear depends
depend:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend
#=============================================================================
# Target rules for targets named squares
# Build rule for target.
squares: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 squares
.PHONY : squares
# fast build rule for target.
squares/fast:
$(MAKE) -f CMakeFiles/squares.dir/build.make CMakeFiles/squares.dir/build
.PHONY : squares/fast
squares.o: squares.cpp.o
.PHONY : squares.o
# target to build an object file
squares.cpp.o:
$(MAKE) -f CMakeFiles/squares.dir/build.make CMakeFiles/squares.dir/squares.cpp.o
.PHONY : squares.cpp.o
squares.i: squares.cpp.i
.PHONY : squares.i
# target to preprocess a source file
squares.cpp.i:
$(MAKE) -f CMakeFiles/squares.dir/build.make CMakeFiles/squares.dir/squares.cpp.i
.PHONY : squares.cpp.i
squares.s: squares.cpp.s
.PHONY : squares.s
# target to generate assembly for a file
squares.cpp.s:
$(MAKE) -f CMakeFiles/squares.dir/build.make CMakeFiles/squares.dir/squares.cpp.s
.PHONY : squares.cpp.s
# Help Target
help:
@echo "The following are some of the valid targets for this Makefile:"
@echo "... all (the default if no target is provided)"
@echo "... clean"
@echo "... depend"
@echo "... edit_cache"
@echo "... rebuild_cache"
@echo "... squares"
@echo "... squares.o"
@echo "... squares.i"
@echo "... squares.s"
.PHONY : help
#=============================================================================
# Special targets to cleanup operation of make.
# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system
================================================
FILE: README.md
================================================
# Playing with C++ OpenCV
**Aim:** Find squares in an image
## To compile and run
> cmake .
> make
> ./squares
### Sample input and output images in /imgs
### References - To improve results
* http://stackoverflow.com/questions/8667818/opencv-c-obj-c-detecting-a-sheet-of-paper-square-detection
* http://stackoverflow.com/questions/10533233/opencv-c-obj-c-advanced-square-detection
* http://stackoverflow.com/questions/14221591/detection-square-opencv-and-c
* http://stackoverflow.com/questions/7755647/opencv-extract-area-of-an-image-from-a-vector-of-squares/7756000#7756000
* http://stackoverflow.com/questions/13523837/find-corner-of-papers/13532779#13532779
* [Automatic perspective correction for quadrilateral objects](https://web.archive.org/web/20160316131624/http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/) - [Code on github](https://github.com/bsdnoobz/opencv-code/blob/master/quad-segmentation.cpp)
* [Detecting simple shapes in an image](https://web.archive.org/web/20150317002418/http://opencv-code.com/tutorials/detecting-simple-shapes-in-an-image/) - [Code on github](https://github.com/bsdnoobz/opencv-code/blob/master/shape-detect.cpp)
================================================
FILE: squares.cpp
================================================
// The "Square Detector" program.
// It loads several images sequentially and tries to find squares in
// each image
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
static void help()
{
cout <<
"\nA program using pyramid scaling, Canny, contours, contour simpification and\n"
"memory storage to find squares in a list of images\n"
"Returns sequence of squares detected on the image.\n"
"the sequence is stored in the specified memory storage\n"
"Call:\n"
"./squares\n"
"Using OpenCV version %s\n" << CV_VERSION << "\n" << endl;
}
int thresh = 50, N = 5;
const char* wndname = "Square Detection Demo";
// helper function:
// finds a cosine of angle between vectors
// from pt0->pt1 and from pt0->pt2
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);
}
// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
static void findSquares( const Mat& image, vector >& squares )
{
squares.clear();
//s Mat pyr, timg, gray0(image.size(), CV_8U), gray;
// down-scale and upscale the image to filter out the noise
//pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
//pyrUp(pyr, timg, image.size());
// blur will enhance edge detection
Mat timg(image);
medianBlur(image, timg, 9);
Mat gray0(timg.size(), CV_8U), gray;
vector > contours;
// find squares in every color plane of the image
for( int c = 0; c < 3; c++ )
{
int ch[] = {c, 0};
mixChannels(&timg, 1, &gray0, 1, ch, 1);
// try several threshold levels
for( int l = 0; l < N; l++ )
{
// hack: use Canny instead of zero threshold level.
// Canny helps to catch squares with gradient shading
if( l == 0 )
{
// apply Canny. Take the upper threshold from slider
// and set the lower to 0 (which forces edges merging)
Canny(gray0, gray, 5, thresh, 5);
// dilate canny output to remove potential
// holes between edge segments
dilate(gray, gray, Mat(), Point(-1,-1));
}
else
{
// apply threshold if l!=0:
// tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
gray = gray0 >= (l+1)*255/N;
}
// find contours and store them all as a list
findContours(gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
vector approx;
// test each contour
for( size_t i = 0; i < contours.size(); i++ )
{
// approximate contour with accuracy proportional
// to the contour perimeter
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
// square contours should have 4 vertices after approximation
// relatively large area (to filter out noisy contours)
// and be convex.
// Note: absolute value of an area is used because
// area may be positive or negative - in accordance with the
// contour orientation
if( approx.size() == 4 &&
fabs(contourArea(Mat(approx))) > 1000 &&
isContourConvex(Mat(approx)) )
{
double maxCosine = 0;
for( int j = 2; j < 5; j++ )
{
// find the maximum cosine of the angle between joint edges
double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
maxCosine = MAX(maxCosine, cosine);
}
// if cosines of all angles are small
// (all angles are ~90 degree) then write quandrange
// vertices to resultant sequence
if( maxCosine < 0.3 )
squares.push_back(approx);
}
}
}
}
}
// the function draws all the squares in the image
static void drawSquares( Mat& image, const vector >& squares )
{
for( size_t i = 0; i < squares.size(); i++ )
{
const Point* p = &squares[i][0];
int n = (int)squares[i].size();
//dont detect the border
if (p-> x > 3 && p->y > 3)
polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, LINE_AA);
}
imshow(wndname, image);
}
int main(int /*argc*/, char** /*argv*/)
{
static const char* names[] = { "imgs/2Stickies.jpg", "imgs/manyStickies.jpg",0 };
help();
namedWindow( wndname, 1 );
vector > squares;
for( int i = 0; names[i] != 0; i++ )
{
Mat image = imread(names[i], 1);
if( image.empty() )
{
cout << "Couldn't load " << names[i] << endl;
continue;
}
findSquares(image, squares);
drawSquares(image, squares);
//imwrite( "out", image );
int c = waitKey();
if( (char)c == 27 )
break;
}
return 0;
}