├── .gitignore
├── README.md
├── SIFT_filterMatches_homography
├── Makefile
├── Project.xcconfig
├── SIFT_filterMatches_homography.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── SIFT_filterMatches_homography Debug.xcscheme
│ │ └── SIFT_filterMatches_homography Release.xcscheme
├── addons.make
├── bin
│ └── data
│ │ ├── .gitkeep
│ │ ├── peeping_tom_crop1-3d.jpg
│ │ ├── peeping_tom_crop1.jpg
│ │ ├── peeping_tom_crop2-3d.jpg
│ │ ├── peeping_tom_crop2.jpg
│ │ └── peeping_tom_scene.jpg
├── config.make
├── openFrameworks-Info.plist
└── src
│ ├── SIFTMatcher.cpp
│ ├── SIFTMatcher.hpp
│ ├── main.cpp
│ ├── ofApp.cpp
│ └── ofApp.h
├── SIFTtest
├── Makefile
├── Project.xcconfig
├── SIFTtest.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── SIFTtest Debug.xcscheme
│ │ └── SIFTtest Release.xcscheme
├── addons.make
├── bin
│ └── data
│ │ ├── .gitkeep
│ │ ├── peeping_tom_1.jpg
│ │ ├── peeping_tom_1_3d.jpg
│ │ └── peeping_tom_2.jpg
├── config.make
├── openFrameworks-Info.plist
└── src
│ ├── main.cpp
│ ├── ofApp.cpp
│ └── ofApp.h
├── griddedHistogram
├── Makefile
├── Project.xcconfig
├── addons.make
├── bin
│ └── data
│ │ ├── .gitkeep
│ │ ├── grid.png
│ │ └── img.jpg
├── config.make
├── griddedHistogram.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── griddedHistogram Debug.xcscheme
│ │ └── griddedHistogram Release.xcscheme
├── openFrameworks-Info.plist
└── src
│ ├── Histogrid.cpp
│ ├── Histogrid.hpp
│ ├── main.cpp
│ ├── ofApp.cpp
│ └── ofApp.h
└── optFlowTest
├── Makefile
├── Project.xcconfig
├── addons.make
├── bin
└── data
│ ├── .gitkeep
│ ├── rearWindow_clip_1-240p.mp4
│ └── rearWindow_clip_1.mp4
├── config.make
├── openFrameworks-Info.plist
├── optFlowTest.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ ├── optFlowTest Debug.xcscheme
│ └── optFlowTest Release.xcscheme
└── src
├── main.cpp
├── ofApp.cpp
└── ofApp.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Some general ignore patterns
2 | build/
3 | obj/
4 | *.o
5 | Debug*/
6 | Release*/
7 | *.mode*
8 | *.app/
9 | *.pyc
10 | .svn/
11 |
12 |
13 | #XCode
14 | *.pbxuser
15 | *.perspective
16 | *.perspectivev3
17 | *.mode1v3
18 | *.mode2v3
19 | #XCode 4
20 | xcuserdata
21 | *.xcworkspace
22 |
23 | #Code::Blocks
24 | *.depend
25 | *.layout
26 |
27 | #Visual Studio
28 | *.sdf
29 | *.opensdf
30 | *.suo
31 | ipch/
32 |
33 | #Eclipse
34 | .metadata
35 | local.properties
36 | .externalToolBuilders
37 |
38 |
39 | # OS-specific ignore patterns
40 |
41 | #Linux
42 | *~
43 | # KDE
44 | .directory
45 |
46 | #OSX
47 | .DS_Store
48 | *.swp
49 | *~.nib
50 | # Thumbnails
51 | ._*
52 |
53 | #Windows
54 | # Windows image file caches
55 | Thumbs.db
56 | # Folder config file
57 | Desktop.ini
58 |
59 | #Android
60 | .csettings
61 | /libs/openFrameworksCompiled/project/android/paths.make
62 |
63 | # Miscellaneous
64 | .mailmap
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenCV oF Experiments
2 |
3 | Code experiments related to computer vision & cinema posts on my [blog](http://www.tylerhenry.com/category/computervision/) at [tylerhenry.com](http://tylerhenry.com).
4 | Mostly using OpenCV and openFrameworks.
5 |
6 | ---
7 |
8 | ### griddedHistogram
9 |
10 | Contains Histogrid class: uses OpenCV calcHist to generate histograms for subsections of an ofImage.
11 | Written in openFrameworks v.9.0 / XCode 7
12 |
13 | *uses addons:* [`ofxCv`](https://github.com/kylemcdonald/ofxCv/) and `ofxOpenCv`
14 |
15 | 
16 |
17 |
18 | ### SIFT_filterMatches_homography
19 |
20 | Updated, more complete SIFT implementation than SIFTtest (see below).
21 | Written in openFrameworks v.9.0 / XCode 7
22 |
23 | *uses addons:* [`ofxCv`](https://github.com/kylemcdonald/ofxCv/) and `ofxOpenCv`
24 |
25 | **Related tutorial**
26 |
27 | [SIFT Implementation in OpenFrameworks, Part 3](http://www.tylerhenry.com/sift-implementation-in-openframeworks-part-3/)
28 |
29 | Updates over SIFTtest:
30 |
31 | * SIFT implementation placed inside SIFTMatcher class
32 | * added keypoint filter to sort out good keypoint matches
33 | * added homography transformation to
34 | calculate 3D warp of query image to train img
35 |
36 | 
37 |
38 | ---
39 |
40 | ### SIFTtest
41 | First test of SIFT algorithm to match features between two images.
42 | Written in openFrameworks v.9.0 / XCode 7
43 |
44 | *uses addons:* [`ofxCv`](https://github.com/kylemcdonald/ofxCv/) and `ofxOpenCv`
45 |
46 | **Related tutorial**
47 |
48 | [SIFT Implementation in OpenFrameworks, Part 2](http://www.tylerhenry.com/sift-implementation-in-openframeworks-part-2/)
49 |
50 | **Intro tutorials**
51 |
52 | 1. [Getting Started](http://www.tylerhenry.com/getting-started/)
53 | 2. [Finding Features](http://www.tylerhenry.com/finding-features/)
54 | 3. [SIFT Implementation in OpenFrameworks, Part 1](http://www.tylerhenry.com/sift-implementation-in-openframeworks-part-1/)
55 |
56 | 
57 |
58 | ---
59 |
60 | ### optFlowTest
61 | Test of optical flow analysis using Farneback algorithm from OpenCV (through ofxCv)
62 | Written in openFrameworks v.9.0 / XCode 7
63 |
64 | *uses addons:* [`ofxCv`](https://github.com/kylemcdonald/ofxCv/), `ofxOpenCv` and `ofxGui`
65 |
66 | Display local motion in video as a flow field, and also:
67 |
68 | * average motion per frame (red line in video center)
69 | * average motion per clip (red line on left)
70 | * track of average motion per clip (blue dot and path)
71 |
72 | ** Related tutorial**
73 |
74 | [Optical Flow, Part 1](http://www.tylerhenry.com/optical-flow-part-1/)
75 |
76 | [](https://www.youtube.com/watch?v=09hFXvW_NMs)
77 | [YouTube sample](https://www.youtube.com/watch?v=09hFXvW_NMs)
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/Makefile:
--------------------------------------------------------------------------------
1 | # Attempt to load a config.make file.
2 | # If none is found, project defaults in config.project.make will be used.
3 | ifneq ($(wildcard config.make),)
4 | include config.make
5 | endif
6 |
7 | # make sure the the OF_ROOT location is defined
8 | ifndef OF_ROOT
9 | OF_ROOT=$(realpath ../../..)
10 | endif
11 |
12 | # call the project makefile!
13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
14 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/Project.xcconfig:
--------------------------------------------------------------------------------
1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
3 | OF_PATH = ../../..
4 |
5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
7 |
8 | //ICONS - NEW IN 0072
9 | ICON_NAME_DEBUG = icon-debug.icns
10 | ICON_NAME_RELEASE = icon.icns
11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/
12 |
13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to:
14 | //ICON_FILE_PATH = bin/data/
15 |
16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS)
17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
18 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/SIFT_filterMatches_homography.xcodeproj/xcshareddata/xcschemes/SIFT_filterMatches_homography Debug.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/SIFT_filterMatches_homography.xcodeproj/xcshareddata/xcschemes/SIFT_filterMatches_homography Release.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/addons.make:
--------------------------------------------------------------------------------
1 | ofxCv
2 | ofxOpenCv
3 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/bin/data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFT_filterMatches_homography/bin/data/.gitkeep
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/bin/data/peeping_tom_crop1-3d.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFT_filterMatches_homography/bin/data/peeping_tom_crop1-3d.jpg
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/bin/data/peeping_tom_crop1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFT_filterMatches_homography/bin/data/peeping_tom_crop1.jpg
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/bin/data/peeping_tom_crop2-3d.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFT_filterMatches_homography/bin/data/peeping_tom_crop2-3d.jpg
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/bin/data/peeping_tom_crop2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFT_filterMatches_homography/bin/data/peeping_tom_crop2.jpg
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/bin/data/peeping_tom_scene.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFT_filterMatches_homography/bin/data/peeping_tom_scene.jpg
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/config.make:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # CONFIGURE PROJECT MAKEFILE (optional)
3 | # This file is where we make project specific configurations.
4 | ################################################################################
5 |
6 | ################################################################################
7 | # OF ROOT
8 | # The location of your root openFrameworks installation
9 | # (default) OF_ROOT = ../../..
10 | ################################################################################
11 | # OF_ROOT = ../../..
12 |
13 | ################################################################################
14 | # PROJECT ROOT
15 | # The location of the project - a starting place for searching for files
16 | # (default) PROJECT_ROOT = . (this directory)
17 | #
18 | ################################################################################
19 | # PROJECT_ROOT = .
20 |
21 | ################################################################################
22 | # PROJECT SPECIFIC CHECKS
23 | # This is a project defined section to create internal makefile flags to
24 | # conditionally enable or disable the addition of various features within
25 | # this makefile. For instance, if you want to make changes based on whether
26 | # GTK is installed, one might test that here and create a variable to check.
27 | ################################################################################
28 | # None
29 |
30 | ################################################################################
31 | # PROJECT EXTERNAL SOURCE PATHS
32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder.
33 | # Like source folders in the PROJECT_ROOT, these paths are subject to
34 | # exlclusion via the PROJECT_EXLCUSIONS list.
35 | #
36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank)
37 | #
38 | # Note: Leave a leading space when adding list items with the += operator
39 | ################################################################################
40 | # PROJECT_EXTERNAL_SOURCE_PATHS =
41 |
42 | ################################################################################
43 | # PROJECT EXCLUSIONS
44 | # These makefiles assume that all folders in your current project directory
45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations
46 | # to look for source code. The any folders or files that match any of the
47 | # items in the PROJECT_EXCLUSIONS list below will be ignored.
48 | #
49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete
50 | # string unless teh user adds a wildcard (%) operator to match subdirectories.
51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is
52 | # treated literally.
53 | #
54 | # (default) PROJECT_EXCLUSIONS = (blank)
55 | #
56 | # Will automatically exclude the following:
57 | #
58 | # $(PROJECT_ROOT)/bin%
59 | # $(PROJECT_ROOT)/obj%
60 | # $(PROJECT_ROOT)/%.xcodeproj
61 | #
62 | # Note: Leave a leading space when adding list items with the += operator
63 | ################################################################################
64 | # PROJECT_EXCLUSIONS =
65 |
66 | ################################################################################
67 | # PROJECT LINKER FLAGS
68 | # These flags will be sent to the linker when compiling the executable.
69 | #
70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs
71 | #
72 | # Note: Leave a leading space when adding list items with the += operator
73 | ################################################################################
74 |
75 | # Currently, shared libraries that are needed are copied to the
76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to
77 | # add a runtime path to search for those shared libraries, since they aren't
78 | # incorporated directly into the final executable application binary.
79 | # TODO: should this be a default setting?
80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs
81 |
82 | ################################################################################
83 | # PROJECT DEFINES
84 | # Create a space-delimited list of DEFINES. The list will be converted into
85 | # CFLAGS with the "-D" flag later in the makefile.
86 | #
87 | # (default) PROJECT_DEFINES = (blank)
88 | #
89 | # Note: Leave a leading space when adding list items with the += operator
90 | ################################################################################
91 | # PROJECT_DEFINES =
92 |
93 | ################################################################################
94 | # PROJECT CFLAGS
95 | # This is a list of fully qualified CFLAGS required when compiling for this
96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS
97 | # defined in your platform specific core configuration files. These flags are
98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below.
99 | #
100 | # (default) PROJECT_CFLAGS = (blank)
101 | #
102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in
103 | # your platform specific configuration file will be applied by default and
104 | # further flags here may not be needed.
105 | #
106 | # Note: Leave a leading space when adding list items with the += operator
107 | ################################################################################
108 | # PROJECT_CFLAGS =
109 |
110 | ################################################################################
111 | # PROJECT OPTIMIZATION CFLAGS
112 | # These are lists of CFLAGS that are target-specific. While any flags could
113 | # be conditionally added, they are usually limited to optimization flags.
114 | # These flags are added BEFORE the PROJECT_CFLAGS.
115 | #
116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.
117 | #
118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)
119 | #
120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.
121 | #
122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)
123 | #
124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the
125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration
126 | # file will be applied by default and further optimization flags here may not
127 | # be needed.
128 | #
129 | # Note: Leave a leading space when adding list items with the += operator
130 | ################################################################################
131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE =
132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG =
133 |
134 | ################################################################################
135 | # PROJECT COMPILERS
136 | # Custom compilers can be set for CC and CXX
137 | # (default) PROJECT_CXX = (blank)
138 | # (default) PROJECT_CC = (blank)
139 | # Note: Leave a leading space when adding list items with the += operator
140 | ################################################################################
141 | # PROJECT_CXX =
142 | # PROJECT_CC =
143 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/openFrameworks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | cc.openFrameworks.ofapp
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | APPL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 | CFBundleIconFile
20 | ${ICON}
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/src/SIFTMatcher.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // SIFTMatcher.cpp
3 | // SIFT_filterMatches_homography
4 | //
5 | // Created by Tyler on 3/24/16.
6 | //
7 | //
8 |
9 | #include "SIFTMatcher.hpp"
10 |
11 |
12 | //--------------------------------------------------------------
13 | // Constructor
14 | //--------------------------------------------------------------
15 |
16 | // default constructor - blank
17 | SIFTMatcher::SIFTMatcher(){
18 | }
19 |
20 |
21 | // actual constructor - always use this
22 | SIFTMatcher::SIFTMatcher(ofImage& _findImg, ofImage& _fieldImg){
23 |
24 | findImg = &_findImg;
25 | fieldImg = &_fieldImg;
26 |
27 | }
28 |
29 | //-------------------------------------------------------------------------
30 | // MATCH
31 | // runs SIFT keypoint detection and feature descriptor on findImg, fieldImg
32 | // then uses cv::BFMatcher to find matches
33 | //-------------------------------------------------------------------------
34 |
35 | void SIFTMatcher::match(){
36 |
37 | // takes in a query image (findImg) and "train" image (fieldImg)
38 | // returns the matches vector (unfiltered)
39 |
40 | // also references findImg, fieldImg as public findImg, fieldImg
41 | // and saves resulting KeyPoints vectors as public variables
42 |
43 |
44 | uint64_t startTime = ofGetElapsedTimeMillis(); // save start time (in ms) for testing speed
45 |
46 |
47 | //---------------------//
48 | //---- LOAD IMAGES ----//
49 | //---------------------//
50 |
51 |
52 |
53 | // convert to grayscale (SIFT works in grayscale)
54 |
55 | findImg->setImageType(OF_IMAGE_GRAYSCALE);
56 | fieldImg->setImageType(OF_IMAGE_GRAYSCALE);
57 |
58 |
59 | // wrap images with Mat class for use with SIFT
60 |
61 | Mat findMat = toCv(*findImg);
62 | Mat fieldMat = toCv(*fieldImg);
63 |
64 |
65 | // print image load time
66 | // --------------
67 | uint64_t loadTime = ofGetElapsedTimeMillis() - startTime; // calc image load time
68 | ofLogNotice("siftMatch") << "took " << loadTime << " ms to prep images" << endl; // print load time to console
69 | startTime = ofGetElapsedTimeMillis(); // reset startTime
70 | // --------------
71 |
72 |
73 |
74 | //------------------------------------//
75 | //---- SIFT DETECTION/DESCRIPTION ----//
76 | //------------------------------------//
77 |
78 |
79 | // ---------------------------------------
80 | // 1. DETECT SIFT keypoints in both images
81 | // ---------------------------------------
82 |
83 |
84 | SiftFeatureDetector detector(2000); // SIFT detector object
85 | /*
86 | // 2000 = max number of keypoints to find
87 | // all optional constructor args, with default values:
88 | // (int nfeatures=0, int nOctaveLayers=3, double contrastThreshold=0.04,
89 | // double edgeThreshold=10, double sigma=1.6);
90 | */
91 |
92 |
93 | // run the detector on each image
94 |
95 | detector.detect(findMat, findKeypoints);
96 | detector.detect(fieldMat, fieldKeypoints);
97 |
98 |
99 | // print results
100 | // --------------
101 | uint64_t detectTime = ofGetElapsedTimeMillis() - startTime; // calculate detection time
102 |
103 | // print # keypoints found to console
104 |
105 | ofLogNotice("SIFTMatcher") << "took " << detectTime << " ms to find keypoints" << endl << endl
106 | << " # keypoints found" << endl
107 | << " -----------------" << endl
108 | << " findImg: " << findKeypoints.size() << endl
109 | << " fieldImg: " << fieldKeypoints.size() << endl;
110 |
111 | startTime = ofGetElapsedTimeMillis(); // reset startTime
112 | // --------------
113 |
114 |
115 | // --------------------------------------
116 | // 2. DESCRIBE SIFT features of keypoints
117 | // --------------------------------------
118 |
119 |
120 | SiftDescriptorExtractor extractor; // SIFT descriptor object
121 |
122 |
123 | Mat findDescriptors, fieldDescriptors; // matrices to hold all features per keypoint in image
124 | // i.e. in each matrix, row 'i' is the list of features for keypoint 'i'
125 |
126 | // run the feature description extractor
127 |
128 | extractor.compute(findMat, findKeypoints, findDescriptors);
129 | extractor.compute(fieldMat, fieldKeypoints, fieldDescriptors);
130 |
131 |
132 | // print results
133 | // --------------
134 | uint64_t describeTime = ofGetElapsedTimeMillis() - startTime; // calculate description time
135 |
136 | // print some statistics on the matrices
137 |
138 | cv::Size findSize = findDescriptors.size(); // size of matrix
139 | cv::Size fieldSize = fieldDescriptors.size();
140 |
141 | ofLogNotice("SIFTMatcher") << "took " << describeTime << " ms to describe features" << endl << endl
142 | << " findImg feature matrix" << endl
143 | << " ----------------------" << endl
144 | << " height: " << findSize.height << ", width: " << findSize.width << endl
145 | << " area: " << findSize.area() << ", non-zero: " << countNonZero(findDescriptors) << endl
146 | << endl
147 | << " fieldImg feature matrix" << endl
148 | << " -----------------------" << endl
149 | << " height: " << fieldSize.height << ", width: " << fieldSize.width << endl
150 | << " area: " << fieldSize.area() << ", non-zero: " << countNonZero(fieldDescriptors) << endl;
151 |
152 | startTime = ofGetElapsedTimeMillis(); // reset startTime
153 | // --------------
154 |
155 |
156 |
157 | //---------------------------------//
158 | //---- FIND MATCHING KEYPOINTS ----//
159 | //---------------------------------//
160 |
161 |
162 | BFMatcher matcher(NORM_L1, true); // Brute-force Matcher object
163 | /*
164 | // loops through every feature in matrix 1, comparing it to every feature in matrix 2
165 | // to find best match in matrix 2
166 |
167 | // NORM_L1 is "normType" - use NORM_L1 or NORM_L2 for SIFT. I think this determines the type of normalization done when determining "distance" (in n-dimensional space) between keypoints
168 | // true is crossCheck boolean - this means that BFMatcher will only return a match when both keypoints find each other as their closest match. This should be set to true to produce more reliable matches, but only if you have a lot of keypoints.
169 | // a good visual example of cross-checking is on StackOverflow: http://stackoverflow.com/questions/11181823/why-we-need-crosscheckmatching-for-feature
170 | // see here for BFMatcher reference: http://docs.opencv.org/3.0-last-rst/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=bfmatcher#bfmatcher
171 | */
172 |
173 | // run the matcher
174 |
175 | matcher.match(findDescriptors, fieldDescriptors, matches);
176 |
177 |
178 | // print results
179 | // --------------
180 | uint64_t matchTime = ofGetElapsedTimeMillis() - startTime; // calculate match time
181 |
182 | ofLogNotice("SIFTMatcher") << "took " << matchTime << " ms to match keypoints" << endl << endl
183 | << " Found " << matches.size() << " matching keypoints" << endl;
184 | // --------------
185 |
186 |
187 | }
188 |
189 |
190 | //--------------------------------------------------------------
191 | // FILTER MATCHES
192 | // using distance calculations
193 | //--------------------------------------------------------------
194 |
195 | void SIFTMatcher::filterMatches(){
196 |
197 | // code referenced from:
198 | // http://docs.opencv.org/3.1.0/d5/d6f/tutorial_feature_flann_matcher.html
199 | // -----------------------------------------------------------------------
200 |
201 | uint64_t startTime = ofGetElapsedTimeMillis(); // get start time for speed test
202 |
203 |
204 | // loop through matches to find min and max distances
205 |
206 | double minDist = 100, maxDist = 0;
207 |
208 | for( int i = 0; i < matches.size(); i++ ) {
209 |
210 | double dist = matches[i].distance; // calc distance in n-dim space
211 |
212 | if (dist < minDist) { minDist = dist; }
213 | if (dist > maxDist) { maxDist = dist; }
214 | }
215 |
216 |
217 | // save only "good" matches
218 | // here, threshold at 2 * minDist or 0.3 * maxDist, whichever is larger
219 | // this is fairly arbitrary
220 |
221 | if (goodMatches.size() > 0){
222 | goodMatches.clear(); // clear the goodMatches vector if it has anything in it
223 | }
224 |
225 | double threshold = max(2 * minDist, 0.3 * maxDist);
226 |
227 | for (int i = 0; i < matches.size(); i++) {
228 |
229 | if (matches[i].distance <= threshold) {
230 |
231 | goodMatches.push_back(matches[i]); // store as good match
232 | }
233 | }
234 |
235 |
236 | // print results
237 | // --------------
238 | uint64_t filterTime = ofGetElapsedTimeMillis() - startTime; // calculate filter time
239 |
240 | ofLogNotice("SIFTMatcher") << "took " << filterTime << " ms to filter matches" << endl << endl
241 | << " calc\'ed minDist: " << minDist << ", maxDist: " << maxDist << endl
242 | << " used treshold of: " << threshold << endl
243 | << " saved " << goodMatches.size() << " out of " << matches.size() << " total matches" << endl;
244 | // --------------
245 |
246 |
247 | }
248 |
249 |
250 | //--------------------------------------------------------------------
251 | // DRAW MATCHES CV
252 | // uses cv::drawMatches() to draw matches visualization into _matchImg
253 | //--------------------------------------------------------------------
254 |
255 | void SIFTMatcher::drawMatchesCv(ofImage& _matchImg, bool bUseGoodMatches){
256 |
257 | //----------------------//
258 | //---- DRAW RESULTS ----//
259 | //----------------------//
260 |
261 | /*
262 | // cv::drawMatches() displays the images side by side,
263 | // with colored circles at each keypoint,
264 | // and lines connecting the matched keypoints.
265 | // It draws into a Mat.
266 | */
267 |
268 | Mat matchMat; // image-matrix to temp store the results visualization
269 |
270 | // draw results visualization into matchMat image-matrix
271 |
272 | // prep findImg and fieldImg as Mat
273 | Mat findMat, fieldMat;
274 | findMat = toCv(*findImg);
275 | fieldMat = toCv(*fieldImg);
276 |
277 | // pointer to matches vector
278 | vector* matchesPtr = &(matches);
279 |
280 | if (bUseGoodMatches){
281 | matchesPtr = &(goodMatches); // or point to goodMatches vector
282 | }
283 |
284 | drawMatches(findMat, findKeypoints, fieldMat, fieldKeypoints, *matchesPtr, matchMat,
285 | /* and optional parameters: */
286 | Scalar::all(-1), Scalar::all(170), vector(), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
287 | /*
288 | // The Scalar::all(-1) through DRAW_RICH_KEYPOINTS parameters are optional.
289 | // I'm copying the default arguments for them, except:
290 | // Scalar(170) which draws the unmatched keypoints in gray
291 | // DRAW_RICH_KEYPOINTS, which draws the size/rotation of the keypoints.
292 | // The default arguments for those would be:
293 | // Scalar::all(-1) for random colors
294 | // cv::DrawMatchesFlags::DEFAULT for drawing all keypoints as little circles.
295 | // see here for drawMatches() reference: http://docs.opencv.org/3.1.0/d4/d5d/group__features2d__draw.html#gsc.tab=0
296 | */
297 |
298 | // convert matchMat to matchImg
299 |
300 | toOf(matchMat,_matchImg); // wraps matchMat in ofImage matchImg, allocating as needed
301 | _matchImg.update(); // updates the matchImg texture on the GPU
302 |
303 | // now we can draw matchImg in ofApp::draw()
304 | }
305 |
306 |
307 | //----------------------------------------------------------------------------------
308 | // GET HOMOGRAPHY
309 | // uses cv::findHomography to get transformation values
310 | // between findImg and fieldImg based on matched keypoints
311 | // then transforms findImg corners to match where it is in fieldImg
312 | //----------------------------------------------------------------------------------
313 |
314 | void SIFTMatcher::getHomography(bool bUseGoodMatches){
315 |
316 | uint64_t startTime = ofGetElapsedTimeMillis(); // save start time (in ms) for testing speed
317 |
318 |
319 | vector findPts; // Point2f is cv's ofVec2f
320 | vector fieldPts;
321 |
322 | // pointer to matches vector
323 | vector* matchesPtr = &(matches);
324 |
325 | if (bUseGoodMatches){
326 | matchesPtr = &(goodMatches); // or point to goodMatches vector
327 | }
328 |
329 | for (int i=0; isize(); i++){
330 |
331 | // get original keypoints based on matches
332 |
333 | int findIndex = (*matchesPtr)[i].queryIdx; // get index in findKeypoints of matched keypoint
334 | int fieldIndex = (*matchesPtr)[i].trainIdx; // get index in fieldKeypoints of matched keypoint
335 |
336 | Point2f& findPt = findKeypoints[findIndex].pt; // get 2D location of findKeypoint
337 | Point2f& fieldPt = fieldKeypoints[fieldIndex].pt; // get 2D location of fieldKeypoint
338 |
339 | // save in vectors
340 | findPts.push_back(findPt);
341 | fieldPts.push_back(fieldPt);
342 |
343 | }
344 |
345 | // calculate homography matrix using RANSAC method
346 |
347 | Mat H = findHomography(findPts, fieldPts, RANSAC);
348 |
349 | // prep findImg and fieldImg as Mats
350 |
351 | Mat findMat = toCv(*findImg);
352 | Mat fieldMat = toCv(*fieldImg);
353 |
354 | // get the image corners of findMat
355 |
356 | vector findMatCorners(4);
357 | findMatCorners[0] = cvPoint(0,0);
358 | findMatCorners[1] = cvPoint( findMat.cols, 0 );
359 | findMatCorners[2] = cvPoint( findMat.cols, findMat.rows );
360 | findMatCorners[3] = cvPoint( 0, findMat.rows );
361 |
362 | // transform findMat corners to correspond with matched keypoints in fieldImg
363 |
364 | vector fieldMatCorners(4); // we'll save the transformed corners here
365 |
366 | perspectiveTransform(findMatCorners, fieldMatCorners, H); // perform transformation using homography matrix
367 |
368 |
369 | // now convert fieldMatCorners to an ofVec2f vector for use in openFrameworks
370 |
371 | fieldCorners.clear();
372 | for (int i=0; i<4; i++){
373 | fieldCorners.push_back(toOf(fieldMatCorners[i]));
374 | }
375 |
376 |
377 |
378 | // print results
379 | // --------------
380 | uint64_t hTime = ofGetElapsedTimeMillis() - startTime; // calculate homography transform time
381 |
382 | ofLogNotice("SIFTMatcher") << "took " << hTime << " ms to do homography transform" << endl << endl
383 | << " x,y corners of findImg in fieldImg" << endl
384 | << " ----------------------------------" << endl
385 | << " " << fieldCorners[0].x << ", " << fieldCorners[0].y << endl
386 | << " " << fieldCorners[1].x << ", " << fieldCorners[1].y << endl
387 | << " " << fieldCorners[2].x << ", " << fieldCorners[2].y << endl
388 | << " " << fieldCorners[3].x << ", " << fieldCorners[3].y << endl;
389 | // --------------
390 |
391 | }
392 |
393 |
394 | //----------------------------------------------------------------------------------
395 | // DRAW HOMOGRAPHY
396 | //----------------------------------------------------------------------------------
397 |
398 | void SIFTMatcher::drawHomography(float xOffset, float yOffset, ofColor color, float lineWidth){
399 |
400 | ofPushStyle();
401 | ofSetColor(color);
402 | ofSetLineWidth(lineWidth);
403 |
404 | ofPushMatrix();
405 | ofTranslate(xOffset,yOffset);
406 |
407 | ofDrawLine(fieldCorners[0],fieldCorners[1]);
408 | ofDrawLine(fieldCorners[1],fieldCorners[2]);
409 | ofDrawLine(fieldCorners[2],fieldCorners[3]);
410 | ofDrawLine(fieldCorners[3],fieldCorners[0]);
411 |
412 | ofPopMatrix();
413 | ofPopStyle();
414 |
415 | }
416 |
417 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/src/SIFTMatcher.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // SIFTMatcher.hpp
3 | // SIFT_filterMatches_homography
4 | //
5 | // Created by Tyler on 3/24/16.
6 | //
7 | //
8 |
9 | #pragma once
10 | #include "ofMain.h"
11 | #include "ofxOpenCv.h"
12 | #include "ofxCv.h"
13 |
14 | // include non-free OpenCV modules
15 | #include "opencv2/nonfree/nonfree.hpp"
16 |
17 | using namespace cv;
18 | using namespace ofxCv;
19 |
20 | class SIFTMatcher {
21 |
22 | public:
23 |
24 | SIFTMatcher();
25 |
26 | SIFTMatcher(ofImage& _findImg, ofImage& _fieldImg);
27 |
28 | void match();
29 | // returns vector of keypoint matches between "query" image (_findImg) and "train" image (_fieldImg)
30 |
31 | void filterMatches();
32 | // filters outliers in matches vector based on distance
33 |
34 | void drawMatchesCv(ofImage& _matchImg, bool bUseGoodMatches = false);
35 | // draws match visualization into _matchImg
36 | // bUseGoodMatches draws matches vector if false or goodMatches vector if true
37 |
38 | void getHomography(bool bUseGoodMatches = false);
39 | // calculates homography between matched keypoints
40 | // and transforms corners of findImg to match coordinates in fieldImg
41 |
42 | void drawHomography(float xOffset = 0, float yOffset = 0, ofColor color = ofColor::cyan, float lineWidth = 3);
43 | // draws warped box in fieldImg coordinates of where findImg was found
44 | // x and yOffset draw
45 |
46 | ofImage* findImg;
47 | ofImage* fieldImg;
48 |
49 | vector findKeypoints, fieldKeypoints;
50 | vector matches;
51 | vector goodMatches;
52 |
53 | vector fieldCorners; // stores corners of findImg transformed into fieldImg space
54 |
55 |
56 | };
57 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 |
4 | //========================================================================
5 | int main( ){
6 | ofSetupOpenGL(1700,720,OF_WINDOW); // <-------- setup the GL context
7 |
8 | // this kicks off the running of my app
9 | // can be OF_WINDOW or OF_FULLSCREEN
10 | // pass in width and height too:
11 | ofRunApp(new ofApp());
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/src/ofApp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofApp.h"
2 |
3 | //--------------------------------------------------------------
4 | void ofApp::setup(){
5 |
6 | // load the two images as ofImage
7 |
8 | findImg.load("peeping_tom_crop2-3d.jpg"); // image we're looking for (called "query" in OpenCV)
9 | // for findImg here:
10 | // I'm using an image I cropped as a trapezoid from the fieldImg,
11 | // and then warped back to be a square in Photoshop
12 | // (the original crop is "peeping_tom_crop2.jpg")
13 |
14 | fieldImg.load("peeping_tom_scene.jpg"); // image to search in (called "train" in OpenCV)
15 |
16 | // run sift matcher
17 |
18 | siftMatcher = SIFTMatcher(findImg, fieldImg); // construct SIFTMatcher object
19 |
20 | siftMatcher.match(); // find matches
21 |
22 | siftMatcher.filterMatches(); // filter matches
23 |
24 | siftMatcher.drawMatchesCv(matchImg, true); // draw good matches into matchImg
25 |
26 | siftMatcher.getHomography(true); // calculate homography between (good) matched keypoints
27 | // and calc corresponding transformation on findImg
28 |
29 |
30 | // load the pre-warped cropped image for reference in ofApp::draw()
31 | refImg.load("peeping_tom_crop2.jpg");
32 |
33 | }
34 |
35 | //--------------------------------------------------------------
36 | void ofApp::update(){
37 |
38 | }
39 |
40 | //--------------------------------------------------------------
41 | void ofApp::draw(){
42 |
43 | ofBackground(0);
44 |
45 | // draw matchImg
46 | matchImg.draw(0,0);
47 |
48 | /*
49 | // sidenote on drawing Mats:
50 | // -------------------------
51 | // if we had declared matchMat (from setup()) as a public variable in ofApp.h,
52 | // we could draw it in ofApp::draw() using ofxCv's drawMat():
53 | // drawMat(matchMat,0,0);
54 | // but this is expensive since drawMat() allocates a new GPU texture every time it's called.
55 | // it's best to convert to ofImage, so the texture is just allocated once on the GPU
56 | */
57 |
58 | // draw box around findImg inside fieldImg
59 | siftMatcher.drawHomography(findImg.getWidth());
60 | //offset by findImg width to correspond to matchImg
61 |
62 |
63 | // draw the original crop from the image, before I warped it in photoshop
64 | refImg.draw(0,ofGetHeight()-refImg.getHeight());
65 | string refImgLbl = "Original Crop for Reference";
66 | ofDrawBitmapString(refImgLbl, 10, ofGetHeight()-refImg.getHeight()-20);
67 |
68 | }
69 |
70 |
71 | //--------------------------------------------------------------
72 | void ofApp::keyPressed(int key){
73 |
74 | }
75 |
76 | //--------------------------------------------------------------
77 | void ofApp::keyReleased(int key){
78 |
79 | }
80 |
81 | //--------------------------------------------------------------
82 | void ofApp::mouseMoved(int x, int y ){
83 |
84 | }
85 |
86 | //--------------------------------------------------------------
87 | void ofApp::mouseDragged(int x, int y, int button){
88 |
89 | }
90 |
91 | //--------------------------------------------------------------
92 | void ofApp::mousePressed(int x, int y, int button){
93 |
94 | }
95 |
96 | //--------------------------------------------------------------
97 | void ofApp::mouseReleased(int x, int y, int button){
98 |
99 | }
100 |
101 | //--------------------------------------------------------------
102 | void ofApp::mouseEntered(int x, int y){
103 |
104 | }
105 |
106 | //--------------------------------------------------------------
107 | void ofApp::mouseExited(int x, int y){
108 |
109 | }
110 |
111 | //--------------------------------------------------------------
112 | void ofApp::windowResized(int w, int h){
113 |
114 | }
115 |
116 | //--------------------------------------------------------------
117 | void ofApp::gotMessage(ofMessage msg){
118 |
119 | }
120 |
121 | //--------------------------------------------------------------
122 | void ofApp::dragEvent(ofDragInfo dragInfo){
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/SIFT_filterMatches_homography/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofMain.h"
4 | #include "SIFTMatcher.hpp"
5 |
6 | using namespace cv;
7 | using namespace ofxCv;
8 |
9 | class ofApp : public ofBaseApp{
10 |
11 | public:
12 | void setup();
13 | void update();
14 | void draw();
15 |
16 | void keyPressed(int key);
17 | void keyReleased(int key);
18 | void mouseMoved(int x, int y );
19 | void mouseDragged(int x, int y, int button);
20 | void mousePressed(int x, int y, int button);
21 | void mouseReleased(int x, int y, int button);
22 | void mouseEntered(int x, int y);
23 | void mouseExited(int x, int y);
24 | void windowResized(int w, int h);
25 | void dragEvent(ofDragInfo dragInfo);
26 | void gotMessage(ofMessage msg);
27 |
28 | ofImage findImg, fieldImg, matchImg, refImg;
29 | SIFTMatcher siftMatcher;
30 |
31 | };
32 |
--------------------------------------------------------------------------------
/SIFTtest/Makefile:
--------------------------------------------------------------------------------
1 | # Attempt to load a config.make file.
2 | # If none is found, project defaults in config.project.make will be used.
3 | ifneq ($(wildcard config.make),)
4 | include config.make
5 | endif
6 |
7 | # make sure the the OF_ROOT location is defined
8 | ifndef OF_ROOT
9 | OF_ROOT=$(realpath ../../..)
10 | endif
11 |
12 | # call the project makefile!
13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
14 |
--------------------------------------------------------------------------------
/SIFTtest/Project.xcconfig:
--------------------------------------------------------------------------------
1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
3 | OF_PATH = ../../..
4 |
5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
7 |
8 | //ICONS - NEW IN 0072
9 | ICON_NAME_DEBUG = icon-debug.icns
10 | ICON_NAME_RELEASE = icon.icns
11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/
12 |
13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to:
14 | //ICON_FILE_PATH = bin/data/
15 |
16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS)
17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
18 |
--------------------------------------------------------------------------------
/SIFTtest/SIFTtest.xcodeproj/xcshareddata/xcschemes/SIFTtest Debug.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/SIFTtest/SIFTtest.xcodeproj/xcshareddata/xcschemes/SIFTtest Release.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/SIFTtest/addons.make:
--------------------------------------------------------------------------------
1 | ofxCv
2 | ofxOpenCv
3 |
--------------------------------------------------------------------------------
/SIFTtest/bin/data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFTtest/bin/data/.gitkeep
--------------------------------------------------------------------------------
/SIFTtest/bin/data/peeping_tom_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFTtest/bin/data/peeping_tom_1.jpg
--------------------------------------------------------------------------------
/SIFTtest/bin/data/peeping_tom_1_3d.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFTtest/bin/data/peeping_tom_1_3d.jpg
--------------------------------------------------------------------------------
/SIFTtest/bin/data/peeping_tom_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/SIFTtest/bin/data/peeping_tom_2.jpg
--------------------------------------------------------------------------------
/SIFTtest/config.make:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # CONFIGURE PROJECT MAKEFILE (optional)
3 | # This file is where we make project specific configurations.
4 | ################################################################################
5 |
6 | ################################################################################
7 | # OF ROOT
8 | # The location of your root openFrameworks installation
9 | # (default) OF_ROOT = ../../..
10 | ################################################################################
11 | # OF_ROOT = ../../..
12 |
13 | ################################################################################
14 | # PROJECT ROOT
15 | # The location of the project - a starting place for searching for files
16 | # (default) PROJECT_ROOT = . (this directory)
17 | #
18 | ################################################################################
19 | # PROJECT_ROOT = .
20 |
21 | ################################################################################
22 | # PROJECT SPECIFIC CHECKS
23 | # This is a project defined section to create internal makefile flags to
24 | # conditionally enable or disable the addition of various features within
25 | # this makefile. For instance, if you want to make changes based on whether
26 | # GTK is installed, one might test that here and create a variable to check.
27 | ################################################################################
28 | # None
29 |
30 | ################################################################################
31 | # PROJECT EXTERNAL SOURCE PATHS
32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder.
33 | # Like source folders in the PROJECT_ROOT, these paths are subject to
34 | # exlclusion via the PROJECT_EXLCUSIONS list.
35 | #
36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank)
37 | #
38 | # Note: Leave a leading space when adding list items with the += operator
39 | ################################################################################
40 | # PROJECT_EXTERNAL_SOURCE_PATHS =
41 |
42 | ################################################################################
43 | # PROJECT EXCLUSIONS
44 | # These makefiles assume that all folders in your current project directory
45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations
46 | # to look for source code. The any folders or files that match any of the
47 | # items in the PROJECT_EXCLUSIONS list below will be ignored.
48 | #
49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete
50 | # string unless teh user adds a wildcard (%) operator to match subdirectories.
51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is
52 | # treated literally.
53 | #
54 | # (default) PROJECT_EXCLUSIONS = (blank)
55 | #
56 | # Will automatically exclude the following:
57 | #
58 | # $(PROJECT_ROOT)/bin%
59 | # $(PROJECT_ROOT)/obj%
60 | # $(PROJECT_ROOT)/%.xcodeproj
61 | #
62 | # Note: Leave a leading space when adding list items with the += operator
63 | ################################################################################
64 | # PROJECT_EXCLUSIONS =
65 |
66 | ################################################################################
67 | # PROJECT LINKER FLAGS
68 | # These flags will be sent to the linker when compiling the executable.
69 | #
70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs
71 | #
72 | # Note: Leave a leading space when adding list items with the += operator
73 | ################################################################################
74 |
75 | # Currently, shared libraries that are needed are copied to the
76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to
77 | # add a runtime path to search for those shared libraries, since they aren't
78 | # incorporated directly into the final executable application binary.
79 | # TODO: should this be a default setting?
80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs
81 |
82 | ################################################################################
83 | # PROJECT DEFINES
84 | # Create a space-delimited list of DEFINES. The list will be converted into
85 | # CFLAGS with the "-D" flag later in the makefile.
86 | #
87 | # (default) PROJECT_DEFINES = (blank)
88 | #
89 | # Note: Leave a leading space when adding list items with the += operator
90 | ################################################################################
91 | # PROJECT_DEFINES =
92 |
93 | ################################################################################
94 | # PROJECT CFLAGS
95 | # This is a list of fully qualified CFLAGS required when compiling for this
96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS
97 | # defined in your platform specific core configuration files. These flags are
98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below.
99 | #
100 | # (default) PROJECT_CFLAGS = (blank)
101 | #
102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in
103 | # your platform specific configuration file will be applied by default and
104 | # further flags here may not be needed.
105 | #
106 | # Note: Leave a leading space when adding list items with the += operator
107 | ################################################################################
108 | # PROJECT_CFLAGS =
109 |
110 | ################################################################################
111 | # PROJECT OPTIMIZATION CFLAGS
112 | # These are lists of CFLAGS that are target-specific. While any flags could
113 | # be conditionally added, they are usually limited to optimization flags.
114 | # These flags are added BEFORE the PROJECT_CFLAGS.
115 | #
116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.
117 | #
118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)
119 | #
120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.
121 | #
122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)
123 | #
124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the
125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration
126 | # file will be applied by default and further optimization flags here may not
127 | # be needed.
128 | #
129 | # Note: Leave a leading space when adding list items with the += operator
130 | ################################################################################
131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE =
132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG =
133 |
134 | ################################################################################
135 | # PROJECT COMPILERS
136 | # Custom compilers can be set for CC and CXX
137 | # (default) PROJECT_CXX = (blank)
138 | # (default) PROJECT_CC = (blank)
139 | # Note: Leave a leading space when adding list items with the += operator
140 | ################################################################################
141 | # PROJECT_CXX =
142 | # PROJECT_CC =
143 |
--------------------------------------------------------------------------------
/SIFTtest/openFrameworks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | cc.openFrameworks.ofapp
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | APPL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 | CFBundleIconFile
20 | ${ICON}
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SIFTtest/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 |
4 | //========================================================================
5 | int main( ){
6 | ofSetupOpenGL(1700,720,OF_WINDOW); // <-------- setup the GL context
7 |
8 | // this kicks off the running of my app
9 | // can be OF_WINDOW or OF_FULLSCREEN
10 | // pass in width and height too:
11 | ofRunApp(new ofApp());
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/SIFTtest/src/ofApp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofApp.h"
2 |
3 | //--------------------------------------------------------------
4 | void ofApp::setup(){
5 |
6 | // save start time (in ms) for testing speed
7 | uint64_t startTime = ofGetElapsedTimeMillis();
8 |
9 |
10 | //---------------------//
11 | //---- LOAD IMAGES ----//
12 | //---------------------//
13 |
14 | // load the two images as ofImage
15 |
16 | findImg.load("peeping_tom_1.jpg"); // image we're looking for (called "query" in OpenCV)
17 | fieldImg.load("peeping_tom_2.jpg"); // image to search in (called "train" in OpenCV)
18 |
19 | // convert to grayscale (SIFT works in grayscale)
20 |
21 | findImg.setImageType(OF_IMAGE_GRAYSCALE);
22 | fieldImg.setImageType(OF_IMAGE_GRAYSCALE);
23 |
24 |
25 |
26 | // wrap images with Mat class for use with SIFT
27 |
28 | Mat findMat = toCv(findImg);
29 | Mat fieldMat = toCv(fieldImg);
30 |
31 |
32 |
33 | uint64_t loadTime = ofGetElapsedTimeMillis() - startTime; // calc image load time
34 | ofLogNotice("Image Load") << "took " << loadTime << " ms" << endl; // print load time to console
35 | startTime = ofGetElapsedTimeMillis(); // reset startTime
36 |
37 |
38 |
39 | //------------------------------------//
40 | //---- SIFT DETECTION/DESCRIPTION ----//
41 | //------------------------------------//
42 |
43 |
44 | // ---------------------------------------
45 | // 1. DETECT SIFT keypoints in both images
46 | // ---------------------------------------
47 |
48 |
49 | SiftFeatureDetector detector(2000); // SIFT detector object
50 |
51 | // 400 = max number of keypoints to find
52 | // all optional constructor args, with default values:
53 | // (int nfeatures=0, int nOctaveLayers=3, double contrastThreshold=0.04,
54 | // double edgeThreshold=10, double sigma=1.6);
55 |
56 |
57 | vector findKeypoints, fieldKeypoints; // KeyPoint vectors to store keypoints detected per image
58 |
59 | // run the detector on each image
60 |
61 | detector.detect(findMat, findKeypoints);
62 | detector.detect(fieldMat, fieldKeypoints);
63 |
64 |
65 | // print results
66 | // --------------
67 | uint64_t detectTime = ofGetElapsedTimeMillis() - startTime; // calculate detection time
68 |
69 | // print # keypoints found to console
70 |
71 | ofLogNotice("SIFT Detector") << "took " << detectTime << " ms" << endl << endl
72 | << "# keypoints found" << endl
73 | << "-----------------" << endl
74 | << " findImg: " << findKeypoints.size() << endl
75 | << " fieldImg: " << fieldKeypoints.size() << endl;
76 |
77 | startTime = ofGetElapsedTimeMillis(); // reset startTime
78 | // --------------
79 |
80 |
81 | // --------------------------------------
82 | // 2. DESCRIBE SIFT features of keypoints
83 | // --------------------------------------
84 |
85 |
86 | SiftDescriptorExtractor extractor; // SIFT descriptor object
87 |
88 |
89 | Mat findDescriptors, fieldDescriptors; // matrices to hold all features per keypoint in image
90 | // i.e. in each matrix, row 'i' is the list of features for keypoint 'i'
91 |
92 | // run the feature description extractor
93 |
94 | extractor.compute(findMat, findKeypoints, findDescriptors);
95 | extractor.compute(fieldMat, fieldKeypoints, fieldDescriptors);
96 |
97 |
98 | // print results
99 | // --------------
100 | uint64_t describeTime = ofGetElapsedTimeMillis() - startTime; // calculate description time
101 |
102 | // print some statistics on the matrices
103 |
104 | cv::Size findSize = findDescriptors.size(); // size of matrix
105 | cv::Size fieldSize = fieldDescriptors.size();
106 |
107 | ofLogNotice("SIFT Descriptor") << "took " << describeTime << " ms" << endl << endl
108 | << "findImg feature matrix" << endl
109 | << "--------------------" << endl
110 | << " height: " << findSize.height << ", width: " << findSize.width << endl
111 | << " area: " << findSize.area() << ", non-zero: " << countNonZero(findDescriptors) << endl
112 | << endl
113 | << "fieldImg feature matrix" << endl
114 | << "--------------------" << endl
115 | << " height: " << fieldSize.height << ", width: " << fieldSize.width << endl
116 | << " area: " << fieldSize.area() << ", non-zero: " << countNonZero(fieldDescriptors) << endl;
117 |
118 | startTime = ofGetElapsedTimeMillis(); // reset startTime
119 | // --------------
120 |
121 |
122 |
123 | //---------------------------------//
124 | //---- FIND MATCHING KEYPOINTS ----//
125 | //---------------------------------//
126 |
127 |
128 | BFMatcher matcher(NORM_L1, true); // Brute-force Matcher object
129 | // loops through every feature in matrix 1, comparing it to every feature in matrix 2
130 | // to find best match in matrix 2
131 |
132 | // NORM_L1 is "normType" - use NORM_L1 or NORM_L2 for SIFT. I think this determines the type of normalization done when determining "distance" (in n-dimensional space) between keypoints
133 | // true is crossCheck boolean - this means that BFMatcher will only return a match when both keypoints find each other as their closest match. This should be set to true to produce more reliable matches, but only if you have a lot of keypoints.
134 | // a good visual example of cross-checking is on StackOverflow: http://stackoverflow.com/questions/11181823/why-we-need-crosscheckmatching-for-feature
135 | // see here for BFMatcher reference: http://docs.opencv.org/3.0-last-rst/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=bfmatcher#bfmatcher
136 |
137 | vector matches; // vector to store matches
138 |
139 | // run the matcher
140 |
141 | matcher.match(findDescriptors, fieldDescriptors, matches);
142 |
143 |
144 | // print results
145 | // --------------
146 |
147 | uint64_t matchTime = ofGetElapsedTimeMillis() - startTime; // calculate match time
148 |
149 | ofLogNotice("Matcher") << "took " << matchTime << " ms" << endl
150 | << "Found " << matches.size() << " matching keypoints" << endl;
151 | // --------------
152 |
153 |
154 | //----------------------//
155 | //---- DRAW RESULTS ----//
156 | //----------------------//
157 |
158 |
159 | // cv::drawMatches() displays the images side by side,
160 | // with colored circles at each keypoint,
161 | // and lines connecting the matched keypoints.
162 | // It draws into a Mat.
163 |
164 | Mat matchMat; // image-matrix to temp store the results visualization
165 |
166 | // draw results visualization into matchMat image-matrix
167 |
168 | drawMatches(findMat, findKeypoints, fieldMat, fieldKeypoints, matches, matchMat,
169 | /* and optional parameters: */
170 | Scalar::all(-1), Scalar::all(170), vector(), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
171 |
172 | // The Scalar::all(-1) through DRAW_RICH_KEYPOINTS parameters are optional.
173 | // I'm copying the default arguments for them, except:
174 | // Scalar(170) which draws the unmatched keypoints in gray
175 | // DRAW_RICH_KEYPOINTS, which draws the size/rotation of the keypoints.
176 | // The default arguments for those would be:
177 | // Scalar::all(-1) for random colors
178 | // cv::DrawMatchesFlags::DEFAULT for drawing all keypoints as little circles.
179 | // see here for drawMatches() reference: http://docs.opencv.org/3.1.0/d4/d5d/group__features2d__draw.html#gsc.tab=0
180 |
181 | // convert matchMat to matchImg
182 |
183 | toOf(matchMat,matchImg); // wraps matchMat in ofImage matchImg, allocating as needed
184 | matchImg.update(); // updates the matchImg texture on the GPU
185 |
186 | // now we can draw matchImg in ofApp::draw()
187 |
188 |
189 | }
190 |
191 | //--------------------------------------------------------------
192 | void ofApp::update(){
193 |
194 | }
195 |
196 | //--------------------------------------------------------------
197 | void ofApp::draw(){
198 |
199 | ofBackground(0);
200 |
201 | // draw matchImg
202 | matchImg.draw(0,0);
203 |
204 |
205 | // sidenote on drawing Mats:
206 | // -------------------------
207 | // if we had declared matchMat (from setup()) as a public variable in ofApp.h,
208 | // we could draw it in ofApp::draw() using ofxCv's drawMat():
209 | // drawMat(matchMat,0,0);
210 | // but this is expensive since drawMat() allocates a new GPU texture every time it's called.
211 | // it's best to convert to ofImage, so the texture is just allocated once on the GPU
212 |
213 | }
214 |
215 | //--------------------------------------------------------------
216 | void ofApp::keyPressed(int key){
217 |
218 | }
219 |
220 | //--------------------------------------------------------------
221 | void ofApp::keyReleased(int key){
222 |
223 | }
224 |
225 | //--------------------------------------------------------------
226 | void ofApp::mouseMoved(int x, int y ){
227 |
228 | }
229 |
230 | //--------------------------------------------------------------
231 | void ofApp::mouseDragged(int x, int y, int button){
232 |
233 | }
234 |
235 | //--------------------------------------------------------------
236 | void ofApp::mousePressed(int x, int y, int button){
237 |
238 | }
239 |
240 | //--------------------------------------------------------------
241 | void ofApp::mouseReleased(int x, int y, int button){
242 |
243 | }
244 |
245 | //--------------------------------------------------------------
246 | void ofApp::mouseEntered(int x, int y){
247 |
248 | }
249 |
250 | //--------------------------------------------------------------
251 | void ofApp::mouseExited(int x, int y){
252 |
253 | }
254 |
255 | //--------------------------------------------------------------
256 | void ofApp::windowResized(int w, int h){
257 |
258 | }
259 |
260 | //--------------------------------------------------------------
261 | void ofApp::gotMessage(ofMessage msg){
262 |
263 | }
264 |
265 | //--------------------------------------------------------------
266 | void ofApp::dragEvent(ofDragInfo dragInfo){
267 |
268 | }
269 |
--------------------------------------------------------------------------------
/SIFTtest/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofMain.h"
4 | #include "ofxOpenCv.h"
5 | #include "ofxCv.h"
6 |
7 | // include non-free OpenCV modules
8 | #include "opencv2/nonfree/nonfree.hpp"
9 |
10 | using namespace cv;
11 | using namespace ofxCv;
12 |
13 | class ofApp : public ofBaseApp{
14 |
15 | public:
16 | void setup();
17 | void update();
18 | void draw();
19 |
20 | void keyPressed(int key);
21 | void keyReleased(int key);
22 | void mouseMoved(int x, int y );
23 | void mouseDragged(int x, int y, int button);
24 | void mousePressed(int x, int y, int button);
25 | void mouseReleased(int x, int y, int button);
26 | void mouseEntered(int x, int y);
27 | void mouseExited(int x, int y);
28 | void windowResized(int w, int h);
29 | void dragEvent(ofDragInfo dragInfo);
30 | void gotMessage(ofMessage msg);
31 |
32 | ofImage findImg, fieldImg, matchImg;
33 |
34 |
35 | };
36 |
--------------------------------------------------------------------------------
/griddedHistogram/Makefile:
--------------------------------------------------------------------------------
1 | # Attempt to load a config.make file.
2 | # If none is found, project defaults in config.project.make will be used.
3 | ifneq ($(wildcard config.make),)
4 | include config.make
5 | endif
6 |
7 | # make sure the the OF_ROOT location is defined
8 | ifndef OF_ROOT
9 | OF_ROOT=$(realpath ../../..)
10 | endif
11 |
12 | # call the project makefile!
13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
14 |
--------------------------------------------------------------------------------
/griddedHistogram/Project.xcconfig:
--------------------------------------------------------------------------------
1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
3 | OF_PATH = ../../..
4 |
5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
7 |
8 | //ICONS - NEW IN 0072
9 | ICON_NAME_DEBUG = icon-debug.icns
10 | ICON_NAME_RELEASE = icon.icns
11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/
12 |
13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to:
14 | //ICON_FILE_PATH = bin/data/
15 |
16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS)
17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
18 |
--------------------------------------------------------------------------------
/griddedHistogram/addons.make:
--------------------------------------------------------------------------------
1 | ofxCcv
2 | ofxCv
3 | ofxGui
4 | ofxOpenCv
5 |
--------------------------------------------------------------------------------
/griddedHistogram/bin/data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/griddedHistogram/bin/data/.gitkeep
--------------------------------------------------------------------------------
/griddedHistogram/bin/data/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/griddedHistogram/bin/data/grid.png
--------------------------------------------------------------------------------
/griddedHistogram/bin/data/img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/griddedHistogram/bin/data/img.jpg
--------------------------------------------------------------------------------
/griddedHistogram/config.make:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # CONFIGURE PROJECT MAKEFILE (optional)
3 | # This file is where we make project specific configurations.
4 | ################################################################################
5 |
6 | ################################################################################
7 | # OF ROOT
8 | # The location of your root openFrameworks installation
9 | # (default) OF_ROOT = ../../..
10 | ################################################################################
11 | # OF_ROOT = ../../..
12 |
13 | ################################################################################
14 | # PROJECT ROOT
15 | # The location of the project - a starting place for searching for files
16 | # (default) PROJECT_ROOT = . (this directory)
17 | #
18 | ################################################################################
19 | # PROJECT_ROOT = .
20 |
21 | ################################################################################
22 | # PROJECT SPECIFIC CHECKS
23 | # This is a project defined section to create internal makefile flags to
24 | # conditionally enable or disable the addition of various features within
25 | # this makefile. For instance, if you want to make changes based on whether
26 | # GTK is installed, one might test that here and create a variable to check.
27 | ################################################################################
28 | # None
29 |
30 | ################################################################################
31 | # PROJECT EXTERNAL SOURCE PATHS
32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder.
33 | # Like source folders in the PROJECT_ROOT, these paths are subject to
34 | # exlclusion via the PROJECT_EXLCUSIONS list.
35 | #
36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank)
37 | #
38 | # Note: Leave a leading space when adding list items with the += operator
39 | ################################################################################
40 | # PROJECT_EXTERNAL_SOURCE_PATHS =
41 |
42 | ################################################################################
43 | # PROJECT EXCLUSIONS
44 | # These makefiles assume that all folders in your current project directory
45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations
46 | # to look for source code. The any folders or files that match any of the
47 | # items in the PROJECT_EXCLUSIONS list below will be ignored.
48 | #
49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete
50 | # string unless teh user adds a wildcard (%) operator to match subdirectories.
51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is
52 | # treated literally.
53 | #
54 | # (default) PROJECT_EXCLUSIONS = (blank)
55 | #
56 | # Will automatically exclude the following:
57 | #
58 | # $(PROJECT_ROOT)/bin%
59 | # $(PROJECT_ROOT)/obj%
60 | # $(PROJECT_ROOT)/%.xcodeproj
61 | #
62 | # Note: Leave a leading space when adding list items with the += operator
63 | ################################################################################
64 | # PROJECT_EXCLUSIONS =
65 |
66 | ################################################################################
67 | # PROJECT LINKER FLAGS
68 | # These flags will be sent to the linker when compiling the executable.
69 | #
70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs
71 | #
72 | # Note: Leave a leading space when adding list items with the += operator
73 | ################################################################################
74 |
75 | # Currently, shared libraries that are needed are copied to the
76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to
77 | # add a runtime path to search for those shared libraries, since they aren't
78 | # incorporated directly into the final executable application binary.
79 | # TODO: should this be a default setting?
80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs
81 |
82 | ################################################################################
83 | # PROJECT DEFINES
84 | # Create a space-delimited list of DEFINES. The list will be converted into
85 | # CFLAGS with the "-D" flag later in the makefile.
86 | #
87 | # (default) PROJECT_DEFINES = (blank)
88 | #
89 | # Note: Leave a leading space when adding list items with the += operator
90 | ################################################################################
91 | # PROJECT_DEFINES =
92 |
93 | ################################################################################
94 | # PROJECT CFLAGS
95 | # This is a list of fully qualified CFLAGS required when compiling for this
96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS
97 | # defined in your platform specific core configuration files. These flags are
98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below.
99 | #
100 | # (default) PROJECT_CFLAGS = (blank)
101 | #
102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in
103 | # your platform specific configuration file will be applied by default and
104 | # further flags here may not be needed.
105 | #
106 | # Note: Leave a leading space when adding list items with the += operator
107 | ################################################################################
108 | # PROJECT_CFLAGS =
109 |
110 | ################################################################################
111 | # PROJECT OPTIMIZATION CFLAGS
112 | # These are lists of CFLAGS that are target-specific. While any flags could
113 | # be conditionally added, they are usually limited to optimization flags.
114 | # These flags are added BEFORE the PROJECT_CFLAGS.
115 | #
116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.
117 | #
118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)
119 | #
120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.
121 | #
122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)
123 | #
124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the
125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration
126 | # file will be applied by default and further optimization flags here may not
127 | # be needed.
128 | #
129 | # Note: Leave a leading space when adding list items with the += operator
130 | ################################################################################
131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE =
132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG =
133 |
134 | ################################################################################
135 | # PROJECT COMPILERS
136 | # Custom compilers can be set for CC and CXX
137 | # (default) PROJECT_CXX = (blank)
138 | # (default) PROJECT_CC = (blank)
139 | # Note: Leave a leading space when adding list items with the += operator
140 | ################################################################################
141 | # PROJECT_CXX =
142 | # PROJECT_CC =
143 |
--------------------------------------------------------------------------------
/griddedHistogram/griddedHistogram.xcodeproj/xcshareddata/xcschemes/griddedHistogram Debug.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/griddedHistogram/griddedHistogram.xcodeproj/xcshareddata/xcschemes/griddedHistogram Release.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/griddedHistogram/openFrameworks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | cc.openFrameworks.ofapp
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | APPL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 | CFBundleIconFile
20 | ${ICON}
21 |
22 |
23 |
--------------------------------------------------------------------------------
/griddedHistogram/src/Histogrid.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Histogrid.cpp
3 | // griddedHistogram
4 | //
5 | // Created by Tyler on 3/31/16.
6 | //
7 | //
8 |
9 | #include "Histogrid.hpp"
10 |
11 |
12 | Histogrid::Histogrid(){
13 |
14 | }
15 |
16 |
17 | Histogrid::Histogrid(ofImage& _img, int _nDivsX, int _nDivsY, int _nBins){
18 |
19 | img = &_img;
20 |
21 | nDivsX = _nDivsX;
22 | nDivsY = _nDivsY;
23 | nBins = _nBins;
24 |
25 | imgMat = toCv(*img);
26 | cvtColor(imgMat,imgMat, CV_BGR2GRAY);
27 | // convert to grayscale for intensity
28 |
29 | }
30 |
31 |
32 | void Histogrid::run(){
33 |
34 | // calculate histograms
35 |
36 | histograms.clear();
37 | rects.clear();
38 |
39 | Mat hist;
40 | float range[] = { 0, 256 }; // histogram range, upper bound exclusive
41 | const float* histRange = { range }; // another range? cv weirdness
42 |
43 | for (int r=0; r tmpHist;
70 | for (int i=0; i(i));
73 |
74 | }
75 | // save to histogram vector of histograms
76 | histograms.push_back(tmpHist);
77 | }
78 | }
79 |
80 |
81 |
82 | }
83 |
84 | void Histogrid::draw(int n, ofColor color){
85 | draw(n,0,0,img->getWidth(),img->getHeight(), color);
86 | // draw at (0,0) and image size
87 | }
88 |
89 | void Histogrid::draw(int n, float x, float y, float w, float h, ofColor color){
90 |
91 | ofPushMatrix();
92 | ofTranslate(x,y);
93 |
94 | ofPushStyle();
95 | ofSetLineWidth(1);
96 | ofFill();
97 | ofSetColor(color);
98 |
99 | for (int i=0; i>& Histogrid::getHistograms() const{
120 |
121 | return histograms; // return all histograms
122 | }
123 |
124 | const vector& Histogrid::getHistogram(int n) const{
125 |
126 | return histograms[n]; // return specific histogram
127 | }
128 |
129 | int Histogrid::getNDivsX(){
130 |
131 | return nDivsX;
132 | }
133 |
134 | int Histogrid::getNDivsY(){
135 |
136 | return nDivsY;
137 | }
138 |
139 | int Histogrid::getNBins(){
140 |
141 | return nBins;
142 | }
143 |
144 | const vector& Histogrid::getRectangles() const{
145 | return rects;
146 | }
--------------------------------------------------------------------------------
/griddedHistogram/src/Histogrid.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // Histogrid.hpp
3 | // griddedHistogram
4 | //
5 | // Created by Tyler on 3/31/16.
6 | //
7 | //
8 |
9 | #pragma once
10 | #include "ofMain.h"
11 |
12 | #include "ofxOpenCv.h"
13 | #include "ofxCv.h"
14 |
15 | using namespace cv;
16 | using namespace ofxCv;
17 |
18 | class Histogrid {
19 |
20 | public:
21 |
22 | Histogrid();
23 | Histogrid(ofImage& _img, int _nDivsX = 10, int _nDivsY = 10, int _nBins = 256);
24 |
25 | void run();
26 | void draw(int n, ofColor color = ofColor::white);
27 | void draw(int n, float x, float y, float w, float h, ofColor color = ofColor::white);
28 | void drawMat();
29 |
30 | const vector>& getHistograms() const;
31 | const vector& getHistogram(int n) const;
32 | int getNDivsX();
33 | int getNDivsY();
34 | int getNBins();
35 | const vector& getRectangles() const;
36 |
37 | private:
38 |
39 | int nDivsX, nDivsY, nBins;
40 | ofImage* img;
41 | Mat imgMat;
42 |
43 | vector> histograms;
44 | vector rects;
45 |
46 | };
47 |
--------------------------------------------------------------------------------
/griddedHistogram/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 |
4 | //========================================================================
5 | int main( ){
6 | ofSetupOpenGL(1280,480,OF_WINDOW); // <-------- setup the GL context
7 |
8 | // this kicks off the running of my app
9 | // can be OF_WINDOW or OF_FULLSCREEN
10 | // pass in width and height too:
11 | ofRunApp(new ofApp());
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/griddedHistogram/src/ofApp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofApp.h"
2 |
3 | //--------------------------------------------------------------
4 | void ofApp::setup(){
5 | ofBackground(0);
6 |
7 | img.load("img.jpg");
8 |
9 | imgXY = ofVec2f(0,0); // placement of image for draw
10 | imgWH = ofVec2f(640,480); // scale of image for draw
11 |
12 | nDivsX = 2; // # of grid divisions on x-axis
13 | nDivsY = 2; // # of divs on y-axis
14 |
15 | hist = Histogrid(img,nDivsX,nDivsY,256); //img, nDivs x,y, nBins
16 |
17 | hist.run(); // calculate the histogram
18 |
19 | rects = hist.getRectangles(); // get the grid as a vector of rectangles
20 |
21 | drawGrid = ofRectangle(0,0,0,0); // rectangle overlay for selected subsection
22 |
23 | }
24 |
25 | //--------------------------------------------------------------
26 | void ofApp::update(){
27 |
28 | }
29 |
30 | //--------------------------------------------------------------
31 | void ofApp::draw(){
32 |
33 | img.draw(imgXY.x,imgXY.y, imgWH.x,imgWH.y); // draw image
34 |
35 | hist.draw(gridNum, imgWH.x,imgXY.y, imgWH.x,imgWH.y); // draw histogram
36 | // gridNum = which section to draw histogram for
37 | // other options: x,y, w,h for draw (here, draw next to image)
38 |
39 |
40 | // draw selected grid chunk
41 |
42 | ofPushMatrix();
43 | ofTranslate(imgXY);
44 | ofScale(imgWH.x/img.getWidth(),imgWH.y/img.getHeight());
45 | ofPushStyle();
46 | ofFill();
47 | ofSetColor(255,255,0,100);
48 | ofDrawRectangle(drawGrid); // draw selected rect
49 | ofPopStyle();
50 | ofPopMatrix();
51 |
52 | }
53 |
54 | //--------------------------------------------------------------
55 | void ofApp::keyPressed(int key){
56 |
57 | }
58 |
59 | //--------------------------------------------------------------
60 | void ofApp::keyReleased(int key){
61 |
62 | }
63 |
64 | //--------------------------------------------------------------
65 | void ofApp::mouseMoved(int x, int y ){
66 |
67 | // if mouse is over image
68 | ofRectangle rect(imgXY,imgWH);
69 |
70 | if (rect.inside(ofVec2f(x,y))){
71 |
72 | // figure out which rectangle the mouse is in
73 |
74 | float mX = ofMap(x, imgXY.x, imgWH.x, 0, img.getWidth());
75 | float mY = ofMap(y, imgXY.y, imgWH.y, 0, img.getHeight());
76 |
77 | for (int i=0; i rects;
37 |
38 | };
39 |
--------------------------------------------------------------------------------
/optFlowTest/Makefile:
--------------------------------------------------------------------------------
1 | # Attempt to load a config.make file.
2 | # If none is found, project defaults in config.project.make will be used.
3 | ifneq ($(wildcard config.make),)
4 | include config.make
5 | endif
6 |
7 | # make sure the the OF_ROOT location is defined
8 | ifndef OF_ROOT
9 | OF_ROOT=$(realpath ../../..)
10 | endif
11 |
12 | # call the project makefile!
13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
14 |
--------------------------------------------------------------------------------
/optFlowTest/Project.xcconfig:
--------------------------------------------------------------------------------
1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
3 | OF_PATH = ../../..
4 |
5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
7 |
8 | //ICONS - NEW IN 0072
9 | ICON_NAME_DEBUG = icon-debug.icns
10 | ICON_NAME_RELEASE = icon.icns
11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/
12 |
13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to:
14 | //ICON_FILE_PATH = bin/data/
15 |
16 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS)
17 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
18 |
--------------------------------------------------------------------------------
/optFlowTest/addons.make:
--------------------------------------------------------------------------------
1 | ofxCv
2 | ofxOpenCv
3 |
--------------------------------------------------------------------------------
/optFlowTest/bin/data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/optFlowTest/bin/data/.gitkeep
--------------------------------------------------------------------------------
/optFlowTest/bin/data/rearWindow_clip_1-240p.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/optFlowTest/bin/data/rearWindow_clip_1-240p.mp4
--------------------------------------------------------------------------------
/optFlowTest/bin/data/rearWindow_clip_1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyhenry/opencv-oF-experiments/9564b74604e37f2a5941219cc95b5612d19721c9/optFlowTest/bin/data/rearWindow_clip_1.mp4
--------------------------------------------------------------------------------
/optFlowTest/config.make:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # CONFIGURE PROJECT MAKEFILE (optional)
3 | # This file is where we make project specific configurations.
4 | ################################################################################
5 |
6 | ################################################################################
7 | # OF ROOT
8 | # The location of your root openFrameworks installation
9 | # (default) OF_ROOT = ../../..
10 | ################################################################################
11 | # OF_ROOT = ../../..
12 |
13 | ################################################################################
14 | # PROJECT ROOT
15 | # The location of the project - a starting place for searching for files
16 | # (default) PROJECT_ROOT = . (this directory)
17 | #
18 | ################################################################################
19 | # PROJECT_ROOT = .
20 |
21 | ################################################################################
22 | # PROJECT SPECIFIC CHECKS
23 | # This is a project defined section to create internal makefile flags to
24 | # conditionally enable or disable the addition of various features within
25 | # this makefile. For instance, if you want to make changes based on whether
26 | # GTK is installed, one might test that here and create a variable to check.
27 | ################################################################################
28 | # None
29 |
30 | ################################################################################
31 | # PROJECT EXTERNAL SOURCE PATHS
32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder.
33 | # Like source folders in the PROJECT_ROOT, these paths are subject to
34 | # exlclusion via the PROJECT_EXLCUSIONS list.
35 | #
36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank)
37 | #
38 | # Note: Leave a leading space when adding list items with the += operator
39 | ################################################################################
40 | # PROJECT_EXTERNAL_SOURCE_PATHS =
41 |
42 | ################################################################################
43 | # PROJECT EXCLUSIONS
44 | # These makefiles assume that all folders in your current project directory
45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations
46 | # to look for source code. The any folders or files that match any of the
47 | # items in the PROJECT_EXCLUSIONS list below will be ignored.
48 | #
49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete
50 | # string unless teh user adds a wildcard (%) operator to match subdirectories.
51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is
52 | # treated literally.
53 | #
54 | # (default) PROJECT_EXCLUSIONS = (blank)
55 | #
56 | # Will automatically exclude the following:
57 | #
58 | # $(PROJECT_ROOT)/bin%
59 | # $(PROJECT_ROOT)/obj%
60 | # $(PROJECT_ROOT)/%.xcodeproj
61 | #
62 | # Note: Leave a leading space when adding list items with the += operator
63 | ################################################################################
64 | # PROJECT_EXCLUSIONS =
65 |
66 | ################################################################################
67 | # PROJECT LINKER FLAGS
68 | # These flags will be sent to the linker when compiling the executable.
69 | #
70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs
71 | #
72 | # Note: Leave a leading space when adding list items with the += operator
73 | ################################################################################
74 |
75 | # Currently, shared libraries that are needed are copied to the
76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to
77 | # add a runtime path to search for those shared libraries, since they aren't
78 | # incorporated directly into the final executable application binary.
79 | # TODO: should this be a default setting?
80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs
81 |
82 | ################################################################################
83 | # PROJECT DEFINES
84 | # Create a space-delimited list of DEFINES. The list will be converted into
85 | # CFLAGS with the "-D" flag later in the makefile.
86 | #
87 | # (default) PROJECT_DEFINES = (blank)
88 | #
89 | # Note: Leave a leading space when adding list items with the += operator
90 | ################################################################################
91 | # PROJECT_DEFINES =
92 |
93 | ################################################################################
94 | # PROJECT CFLAGS
95 | # This is a list of fully qualified CFLAGS required when compiling for this
96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS
97 | # defined in your platform specific core configuration files. These flags are
98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below.
99 | #
100 | # (default) PROJECT_CFLAGS = (blank)
101 | #
102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in
103 | # your platform specific configuration file will be applied by default and
104 | # further flags here may not be needed.
105 | #
106 | # Note: Leave a leading space when adding list items with the += operator
107 | ################################################################################
108 | # PROJECT_CFLAGS =
109 |
110 | ################################################################################
111 | # PROJECT OPTIMIZATION CFLAGS
112 | # These are lists of CFLAGS that are target-specific. While any flags could
113 | # be conditionally added, they are usually limited to optimization flags.
114 | # These flags are added BEFORE the PROJECT_CFLAGS.
115 | #
116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.
117 | #
118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)
119 | #
120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.
121 | #
122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)
123 | #
124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the
125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration
126 | # file will be applied by default and further optimization flags here may not
127 | # be needed.
128 | #
129 | # Note: Leave a leading space when adding list items with the += operator
130 | ################################################################################
131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE =
132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG =
133 |
134 | ################################################################################
135 | # PROJECT COMPILERS
136 | # Custom compilers can be set for CC and CXX
137 | # (default) PROJECT_CXX = (blank)
138 | # (default) PROJECT_CC = (blank)
139 | # Note: Leave a leading space when adding list items with the += operator
140 | ################################################################################
141 | # PROJECT_CXX =
142 | # PROJECT_CC =
143 |
--------------------------------------------------------------------------------
/optFlowTest/openFrameworks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | cc.openFrameworks.ofapp
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | APPL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 | CFBundleIconFile
20 | ${ICON}
21 |
22 |
23 |
--------------------------------------------------------------------------------
/optFlowTest/optFlowTest.xcodeproj/xcshareddata/xcschemes/optFlowTest Debug.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/optFlowTest/optFlowTest.xcodeproj/xcshareddata/xcschemes/optFlowTest Release.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/optFlowTest/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 |
4 | //========================================================================
5 | int main( ){
6 | ofSetupOpenGL(1280,720,OF_WINDOW); // <-------- setup the GL context
7 |
8 | // this kicks off the running of my app
9 | // can be OF_WINDOW or OF_FULLSCREEN
10 | // pass in width and height too:
11 | ofRunApp(new ofApp());
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/optFlowTest/src/ofApp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofApp.h"
2 |
3 | //--------------------------------------------------------------
4 | void ofApp::setup(){
5 | ofBackground(0);
6 | ofSetFrameRate(60);
7 | ofFill();
8 |
9 | vid.load("rearWindow_clip_1-240p.mp4"); // a single shot from Rear Window
10 | vidW = vid.getWidth();
11 | vidH = vid.getHeight();
12 |
13 | // setup gui
14 | gui.setup();
15 | gui.add(flowPyrScale.set("Pyramid Scale", .5, 0, .99));
16 | gui.add(flowLevels.set("Pyramid Levels", 4, 1, 8));
17 | gui.add(flowIterations.set("Iterations", 2, 1, 8));
18 | gui.add(flowPolyN.set("Polynomial size", 7, 5, 10));
19 | gui.add(flowPolySigma.set("PolySigma", 1.5, 1.1, 2));
20 | gui.add(flowUseGaussian.set("Use Gaussian", true));
21 | gui.add(flowWinSize.set("Window size", 32, 4, 64));
22 | gui.add(loopVid.set("Loop video", false));
23 | gui.add(vidScale.set("Scale video", 2, 1, 3));
24 | gui.add(lineWidth.set("Draw line width", 4, 1, 10));
25 |
26 | // start video
27 | vid.play();
28 | }
29 |
30 | //--------------------------------------------------------------
31 | void ofApp::update(){
32 |
33 | if (vid.getCurrentFrame() == 0) {
34 | reset();
35 | // will only do full reset if video is at beginning
36 | // doubles as an initialization
37 | }
38 |
39 | vid.update();
40 |
41 | if (loopVid){
42 | vid.setLoopState(OF_LOOP_NORMAL);
43 |
44 | if (!vid.isPlaying()){
45 | vid.play(); // restart vid if it ended
46 | }
47 |
48 |
49 | } else {
50 | vid.setLoopState(OF_LOOP_NONE);
51 |
52 | if (vid.getIsMovieDone()){
53 | flow.resetFlow(); // reset flow cache in ofxCv to clear flow draw
54 | }
55 | }
56 |
57 |
58 | if (vid.isFrameNew()){
59 |
60 | // Farneback flow parameters
61 | // more info at: http://docs.opencv.org/3.0-beta/modules/video/doc/motion_analysis_and_object_tracking.html#calcopticalflowfarneback
62 |
63 | flow.setPyramidScale(flowPyrScale);
64 | // 0.5 is classical image pyramid (scales image * 0.5 each layer)
65 |
66 | flow.setNumLevels(flowLevels); // number of levels of scaling pyramid
67 | // 1 means only original image is analyzed, no pyramid
68 |
69 | flow.setWindowSize(flowWinSize); // average window size
70 | // larger means robust to noise + better fast motion, but more blurred motion
71 |
72 | flow.setNumIterations(flowIterations); // # iterations of algorithm at each pyramid level
73 |
74 | flow.setPolyN(flowPolyN);
75 | // size of pixel neighborhood used for per-pixel polynomial expansion
76 | // larger means image will be approximated at smooth surfaces, more robust algorithm, more blurred motion
77 |
78 | flow.setPolySigma(flowPolySigma);
79 | // standard deviation of gaussian used to smooth derivates for polynomial expansion
80 | // for PolyN of 5, use PolySigma 1.1
81 | // for PolyN of 7, use PolySigma 1.5
82 |
83 | flow.setUseGaussian(flowUseGaussian);
84 | // use gaussian filter instead of box filter: slower but more accurate
85 | // normally use a larger window with this option
86 |
87 |
88 |
89 | // calculate flow
90 |
91 | flow.calcOpticalFlow(vid);
92 |
93 |
94 |
95 | // save average flows per frame + per vid
96 |
97 | frameFlows.push_back(flow.getAverageFlow());
98 |
99 | vidFlowTotal += frameFlows.back();
100 | vidFlowAvg = vidFlowTotal / frameFlows.size();
101 |
102 | // calculate dot position to show average movement
103 |
104 | dotPos += frameFlows.back();
105 | dotPath.addVertex(dotPos);
106 |
107 | }
108 |
109 | }
110 |
111 | //--------------------------------------------------------------
112 | void ofApp::draw(){
113 |
114 | // draw video and flow field
115 |
116 | ofSetColor(255);
117 |
118 | ofPushMatrix();
119 | ofTranslate(250,0); // make room for gui at left
120 | ofScale(vidScale, vidScale); // scale to vidScale gui choice
121 |
122 |
123 | vid.draw(0,0, vidW, vidH); // draw video at scale
124 |
125 | ofSetLineWidth(1); // draw thin flow field
126 | // (i.e. don't change flow field's line width with gui lineWidth choice)
127 |
128 | flow.draw(0,0, vidW, vidH); // draw flow field at scale
129 |
130 | ofSetLineWidth(lineWidth); // draw other lines based on gui lineWidth
131 |
132 |
133 | // draw dot to track average flow
134 |
135 | ofSetColor(0,255,255);
136 |
137 | ofDrawCircle(dotPos, lineWidth*0.75); // draw dot
138 |
139 | dotPath.draw(); // draw dot's path
140 |
141 | if (frameFlows.size() > 0){
142 | // draw average magnitude and direction of this frame, if we have it
143 |
144 | ofSetColor(255,0,0);
145 |
146 | ofDrawLine(vidW*0.5, vidH*0.5, vidW*0.5+ frameFlows.back().x * 50, vidH*0.5+ frameFlows.back().y * 50);
147 | // scale motion average * 50 for visibility
148 | }
149 |
150 |
151 | ofPopMatrix();
152 |
153 | // draw framerate at bottom of video
154 | ofDrawBitmapStringHighlight(ofToString((int) ofGetFrameRate()) + "fps", 250, vidH*vidScale);
155 |
156 |
157 |
158 | // draw gui
159 | gui.draw();
160 |
161 |
162 |
163 |
164 | // draw average flow per frame and per video as lines
165 |
166 | if (frameFlows.size() > 0){ // only draw if there's been some flow
167 |
168 | ofPushMatrix();
169 | ofTranslate(125,300); // move below gui
170 |
171 | // draw avg magnitude + direction
172 |
173 | ofSetColor(255,0,0);
174 | ofDrawLine(0, 0, vidFlowAvg.x * 50, vidFlowAvg.y * 50); // scale up * 50 for visibility
175 |
176 | ofSetColor(0,255,0);
177 |
178 | // draw normalized direction for magnitude reference
179 |
180 | ofDrawCircle(vidFlowAvg.getNormalized().x * 50, vidFlowAvg.getNormalized().y * 50, lineWidth);
181 |
182 | ofDrawBitmapStringHighlight("Avg magnitude + direction\nnorm'd to 50px",-115,-50);
183 |
184 |
185 | ofPopMatrix();
186 |
187 | }
188 |
189 |
190 | }
191 |
192 | //--------------------------------------------------------------
193 | void ofApp::reset(){
194 |
195 | flow.resetFlow(); // clear ofxCv's flow cache
196 |
197 | // reset frameFlow tracking
198 | frameFlows.clear();
199 | vidFlowTotal.set(0,0);
200 |
201 | // moving dot
202 | dotPos = ofVec2f(vidW*0.5, vidH*0.5); // center of drawn video
203 |
204 | // polyline that tracks dot movement
205 | dotPath.clear();
206 | dotPath.addVertex(dotPos);
207 | }
208 |
209 | //--------------------------------------------------------------
210 | void ofApp::keyPressed(int key){
211 |
212 | }
213 |
214 | //--------------------------------------------------------------
215 | void ofApp::keyReleased(int key){
216 |
217 | }
218 |
219 | //--------------------------------------------------------------
220 | void ofApp::mouseMoved(int x, int y ){
221 |
222 | }
223 |
224 | //--------------------------------------------------------------
225 | void ofApp::mouseDragged(int x, int y, int button){
226 |
227 | }
228 |
229 | //--------------------------------------------------------------
230 | void ofApp::mousePressed(int x, int y, int button){
231 |
232 | }
233 |
234 | //--------------------------------------------------------------
235 | void ofApp::mouseReleased(int x, int y, int button){
236 |
237 | }
238 |
239 | //--------------------------------------------------------------
240 | void ofApp::mouseEntered(int x, int y){
241 |
242 | }
243 |
244 | //--------------------------------------------------------------
245 | void ofApp::mouseExited(int x, int y){
246 |
247 | }
248 |
249 | //--------------------------------------------------------------
250 | void ofApp::windowResized(int w, int h){
251 |
252 | }
253 |
254 | //--------------------------------------------------------------
255 | void ofApp::gotMessage(ofMessage msg){
256 |
257 | }
258 |
259 | //--------------------------------------------------------------
260 | void ofApp::dragEvent(ofDragInfo dragInfo){
261 |
262 | }
263 |
--------------------------------------------------------------------------------
/optFlowTest/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofMain.h"
4 |
5 | #include "ofxOpenCv.h"
6 | #include "ofxCv.h"
7 |
8 | #include "ofxGui.h"
9 |
10 | using namespace cv;
11 | using namespace ofxCv;
12 |
13 | class ofApp : public ofBaseApp{
14 |
15 | public:
16 | void setup();
17 | void update();
18 | void draw();
19 |
20 | void reset();
21 |
22 | void keyPressed(int key);
23 | void keyReleased(int key);
24 | void mouseMoved(int x, int y );
25 | void mouseDragged(int x, int y, int button);
26 | void mousePressed(int x, int y, int button);
27 | void mouseReleased(int x, int y, int button);
28 | void mouseEntered(int x, int y);
29 | void mouseExited(int x, int y);
30 | void windowResized(int w, int h);
31 | void dragEvent(ofDragInfo dragInfo);
32 | void gotMessage(ofMessage msg);
33 |
34 | ofVideoPlayer vid;
35 | float vidW, vidH;
36 |
37 | FlowFarneback flow; // ofxCv's dense optical flow analyzer (for whole image)
38 | // alternative would be FlowPyrLK which detects/analyzes a sparse feature set
39 |
40 | vector frameFlows; // store average flow frame-by-frame
41 | ofVec2f vidFlowTotal = ofVec2f(0,0), vidFlowAvg = ofVec2f(0,0); // store average flow of video
42 |
43 | // moving dot
44 | ofVec2f dotPos;
45 | ofPolyline dotPath; // polyline tracks dot movement
46 |
47 |
48 | // gui options - stolen from ofxCv example-flow
49 | ofxPanel gui;
50 | ofParameter flowPyrScale, flowPolySigma, vidScale, lineWidth;
51 | ofParameter flowLevels, flowIterations, flowPolyN, flowWinSize;
52 | ofParameter flowUseGaussian, loopVid;
53 |
54 | };
55 |
--------------------------------------------------------------------------------