-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Scripts
It is possible to create your own workflow using the functions that come with PhenotyperCV if you are familiar with C++. The functions that make up PhenotyperCV exist in header files so all you have to do is add a single include #include <phenotypercv.h>
to your source file and link the files when compiling. For instance if you'd like to combine parts of the ChArUco workflow with parts of the machine learning workflow, you can do that in a custom workflow. Full disclosure, I do not have documentation for the individual functions (yet). You will need to look at the header files and determine the proper parameters. An example of a custom source file, cmake file, and commands to link all the headers is here.
#include <phenotypercv.h>
namespace {
const char* keys =
"{i||Input image}"
"{s||Shapes file}"
"{l||Leaves file}"
"{debug||debug}";
}
int main(int argc, char *argv[]){
CommandLineParser parser(argc, argv, keys);
//---------- EXAMPLE OF CUSTOM WORKFLOW ------------
Mat inputImage = imread(parser.get<string>("i"));
//-- Convert to Lab colorspace
Mat lab;
cvtColor(inputImage, lab, cv::COLOR_BGR2Lab);
vector<Mat> split_lab;
split(lab, split_lab);
//-- Threshold b-channel
Mat b_thresh1;
inRange(split_lab[2],133,255,b_thresh1);
//-- Threshold l-channel
Mat l_thresh1;
inRange(split_lab[0],52,128,l_thresh1);
//-- Logical AND
Mat mask1 = b_thresh1 & l_thresh1;
//-- Erode then dilate by 1
Mat mask1_er;
erode(mask1,mask1_er, Mat(), Point(-1, -1), 1, 1, 1);
Mat mask1_dil;
dilate(mask1_er,mask1_dil, Mat(), Point(-1, -1), 1, 1, 1);
//-- ROI inclusion
Mat mask1_roi;
vector<Point> cc_mask1 = keep_roi(mask1_dil,Point(1908,1712),Point(3228,2600),mask1_roi);
//-- Getting and writing shapes data
vector<double> shapes_data = get_shapes(cc_mask1,mask1_roi);
write_shapes(shapes_data,parser.get<string>("i"),parser.get<string>("s"));
//-- If desired, write out mask
if(parser.has("debug")){
vector<string> sub_str;
const string full_str = string(parser.get<string>("i"));
char del = '.';
split(full_str,del,sub_str);
string new_name = sub_str[0]+"_mask.png";
imwrite(new_name,mask1_roi);
}
//-- If desired, segmenting leaves from stem
if(parser.has("l")){
//-- Dilate mask
Mat dil;
dilate(mask1_roi, dil, Mat(), Point(-1, -1), 1, 1, 1);
//-- Thinning
Mat skel;
ximgproc::thinning(dil,skel,THINNING_ZHANGSUEN);
//-- Length filter #1
Mat skel_filt0 = length_filter(skel,50);
//-- Prune skeleton
Mat pruned = prune(skel_filt0,5);
//-- Break skeleton into pieces
Mat seg_skel = segment_skeleton(pruned);
//-- Find leaf tips
Mat tips = find_endpoints(pruned);
//-- Remove bad tips
Mat no_tips = Mat::zeros(inputImage.size(),pruned.type());
rectangle(no_tips,Point(2478,2568),Point(2591,2654),255,cv::FILLED);
tips = tips -(tips & no_tips);
//-- Length filter #2
Mat skel_filt1 = length_filter(seg_skel,12);
//-- Identify leaf blades
Mat leaves = find_leaves(skel_filt1,tips);
//-- Anything not-leaf becomes stem
Mat classified = add_stem(leaves,pruned);
//-- Fill original mask with classification
Mat filled_mask = fill_mask(dil,classified);
//-- Getting and writing shapes data
vector<vector<double> > leaf_data = get_leaf_info(classified,filled_mask);
write_leaves(leaf_data,parser.get<string>("i"),parser.get<string>("l"));
//-- If desired, write out filled mask
if(parser.has("debug")){
vector<string> sub_str;
const string full_str = string(parser.get<string>("i"));
char del = '.';
split(full_str,del,sub_str);
string new_name = sub_str[0]+"_filled.png";
imwrite(new_name,filled_mask);
}
}
//----------------- END EXAMPLE --------------------
return(0);
}
# Should only have to modify these three lines
#----------------------------------------------------------------------------
set(Project_name your_project)
set(PhenotyperCV_dir "/path/to/ddpsc_phenotypercv")
set(your_file "main.cpp")
#----------------------------------------------------------------------------
project (${Project_name})
cmake_minimum_required (VERSION 2.6)
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_FLAGS -Wno-narrowing)
find_package(OpenCV REQUIRED)
find_package (Eigen3 REQUIRED NO_MODULE)
find_library(ZBAR_LIBRARIES NAMES zbar)
find_path(ZBAR_INCLUDE_DIR Decoder.h PATH_SUFFIXES zbar)
include_directories(/usr/local/include)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${PhenotyperCV_dir}/include)
add_executable(${Project_name} ${your_file})
target_link_libraries(${Project_name} ${OpenCV_LIBS} ${ZBAR_LIBRARIES})
Then in the directory of your source and cmake files
mkdir build && cd build
cmake ..
make
To see all the different functions that are already made, please see the header files for a full list of what each header file contains. Again full documentation is coming but for now you just have to look.