Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <opencv\highgui.h>
- #include <opencv\cv.h>
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <stdlib.h>
- #include <iostream>
- #include <stdio.h>
- #include <list>
- #include <cmath>
- #include <string>
- #include <opencv2\ml\ml.hpp>
- #include <Windows.h>
- using namespace std;
- using namespace cv;
- //Zooming functions
- Mat zoomIn(int, int);
- Mat zoomOut(int, int);
- static void onMouse(int event, int, int, int /*flags*/, void* /*param*/);
- void info();
- void zoom(Mat);
- //Our functions
- void Morphology_Operations();
- void contourDetection();
- void draw(int&, vector<Point>&, string);
- ///////////////////////////Global Variables//////////////////////////////
- IplImage* frame = 0;
- IplImage* imgGrayscale;
- Point2f pCen;
- //Holds all the detected contours
- vector<vector<Point>> contours;
- //Window variables
- HWND console;
- HWND look;
- //Zooming variables
- Mat imagenOriginal, imagen, imagenMostrar;
- int zoomRec = 500;
- int mousex, mousey;
- int maxRec;
- bool last = false;
- //Erosion dialtion variables
- Mat src, invsrc, dst;
- int morph_elem = 0;
- int morph_size = 9;
- int morph_operator = 0;
- int const max_operator = 4;
- int const max_elem = 2;
- int const max_kernel_size = 21;
- /////////////
- int main(){
- console = GetConsoleWindow();
- cout << "Loading image....";
- //Input image here
- frame = cvLoadImage("train6.jpg");
- src = Mat(frame); //Convert to Mat
- //Find the largest side of the picture
- if (src.rows > src.cols){
- maxRec = src.cols-10;
- }
- else
- maxRec = src.rows-10;
- //Create blank image
- imgGrayscale = cvCreateImage(cvGetSize(frame), 8, 1);
- cout << "\n\nChanging from color to gray...";
- //Change picture from color to gray
- cvCvtColor(frame, imgGrayscale, CV_BGR2GRAY);
- cout << "\n\nThresholding image...";
- //Threshold image to black and white
- cvThreshold(imgGrayscale, imgGrayscale, 85, 255, 1);
- // ERODE AND DILATE HERE!!! #####################################
- //*/
- src = imgGrayscale; //Convert to Mat
- bitwise_not(src, invsrc); // inverts image
- cout << "\n\nEroding and dialating....";
- Morphology_Operations(); //Erode and dialate
- //###############################################################
- ////////Start of Contour detection///////////////////////////
- system("cls");
- info();
- contourDetection();
- cout << "Finished!! Here is the final result." << endl;
- //Put the console in the foreground
- SetForegroundWindow(console);
- last = true;
- //Change how much you zoom
- zoomRec = maxRec*.50;
- //Show your results
- zoom(Mat(frame));
- //Used to check the result of the erosion and dialation
- //zoom(dst);
- waitKey(0);
- //Clean up used images
- cvReleaseImage(&frame);
- cvDestroyAllWindows();
- return 0;
- }
- //Draw function takes in a contour and draws it a given color ("green", "red", or "orange")
- void draw(vector<Point>& conts, string color)
- {
- //Total points on the contour
- int totPoints = conts.size();
- //Loop through all the points on the contour
- for (int j = 0; j < totPoints - 1; j++)
- {
- if (color == "green")
- cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 255, 0), 1);
- else if (color == "red")
- cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 0, 255), 1);
- else if (color == "orange")
- cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 115, 255), 1);
- //On the last point connect to the first point
- if (j == conts.size() - 1){
- if (color == "green")
- cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 255, 0), 1);
- else if (color == "red")
- cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 0, 255), 1);
- else if (color == "orange")
- cvLine(frame, conts[j], conts[j + 1], cvScalar(0, 115, 255), 1);
- break;
- }
- }
- }
- //Uppercase all characters in a string
- string strUpper(string str){
- int i = 0;
- while (str[i]){
- str[i] = toupper(str[i]);
- i++;
- }
- return str;
- }
- //Start the contour detection
- void contourDetection(){
- //Vector that represents the hierarchy of the contours
- vector< Vec4i > hierarchy;
- ///Find contours and store in a contours, then store the contour hierarchies in hierarchy
- cv::findContours(dst, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
- double area;
- int count = 0, all = 0;
- CvSVM detector;
- bool exit = false;
- vector<vector<double>> allData;
- vector<float> labels;
- //Load the training data
- detector.load("Muskrat_Counting_SVM.xml");
- //Size of the whole picture
- int totSize = dst.total();
- //Iterate through all parent contours
- for (int i = 0; i < contours.size() && exit == false; i = hierarchy[i][0])
- {
- //Find the size of the outer contours (lakes)
- area = contourArea(contours[i]);
- //Find the biggest contours (presumed to be the lakes)**Needs optimization
- if (area > totSize*.20)// && area < totSize*.5)
- {
- //Draw the lake
- draw(contours[i], "red");
- //Using hierarchy array to determine hierarchy, this loop is for the child contours
- for (int j = hierarchy[i][2]; hierarchy[j][0] > 0 && exit == false; j = hierarchy[j][0]){
- //Find contour size
- double contArea = contourArea(contours[j]);
- if (contArea > 20 && contArea < 300){ //When size of the contour is inbetween those area
- //Get the location of the center of the contour for zooming
- Moments mu = moments(contours[j], false);
- pCen = Point2f(mu.m10 / mu.m00, mu.m01 / mu.m00);
- all++;
- //Draw current contour
- draw(contours[j], "orange");
- //Evaluate next contour
- zoom(Mat(frame));
- //Output question
- cout << "Is this a contour? (Y or N) ";
- string input;
- while (exit == false){
- //Retrieve user input
- getline(cin, input);
- cout << endl;
- cout << "\n\nGetting next contour...";
- //If user enters Y
- if (strUpper(input) == "Y" || strUpper(input) == "N")
- {
- if (strUpper(input) == "Y"){
- //Draw the correct contour green
- draw(contours[j], "green");
- //Count the drawn contours
- count++;
- labels.push_back(1);
- }
- else{
- draw(contours[j], "red");
- labels.push_back(-1);
- }
- ///////////////////////###################Get training data############################////////////////////////////
- //Get aspect ratio
- Rect rect = boundingRect(contours[j]);
- double aspect_ratio = float(rect.width) / rect.height;
- //Get extent
- double rect_area = float(rect.width)*rect.height;
- double extent = float(contArea) / rect_area;
- //Get solidity
- vector<Point> hull;
- convexHull(contours[j], hull);
- double hull_area = contourArea(hull);
- double solidity = float(contArea) / hull_area;
- //Get equivalent diameter
- double equi_diameter = sqrt(4 * contArea / 3.14159265);
- //Perimeter
- double perimeter = arcLength(contours[j], true);
- //Compile data
- vector<double> data = { aspect_ratio, extent, solidity, equi_diameter, perimeter, contArea };
- allData.push_back(data);
- //For prediction
- /*float response = detector.predict(trainingData);
- if (response == 1)
- {
- draw(contours[j], "green");
- count++;
- all++;
- }
- else if (response == -1)
- {
- draw(contours[j], "red");
- all++;
- }*/
- ////////////////////////////////////////////.........
- break;
- }
- //Identified as not a push-up (False detection)
- /*else if (strUpper(input) == "N")
- {
- draw(contours[j], "red");
- break;
- }*/
- //Exits training process
- else if (strUpper(input) == "QUIT")
- exit = true;
- //Incorrect entry
- else
- cout << endl << "Enter Y or N..." << endl;
- }
- }
- }
- }
- }
- int amount = allData.size();
- //Produce matrix containing training data
- Mat trainingData(amount, 6, CV_32FC1, &allData);
- //Array to label data
- Mat labelsMat(amount, 1, CV_32FC1, &labels);
- CvSVMParams params; //
- params.svm_type = CvSVM::C_SVC; //Required data for training
- params.kernel_type = CvSVM::LINEAR; //
- //params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); //
- //Append training data to SVM
- detector.train(trainingData, labelsMat, Mat(), Mat(), params);
- //detector.train_auto(trainingData, labelsMat, Mat(), Mat(), params);
- //Save the machine learning data
- detector.save("Muskrat_Counting_SVM.xml");
- system("cls");
- info();
- cout << "\n\nTotal Circled: " << count << endl; //Output how many contours that were detected
- cout << "Total: " << all << endl; //Total amount of contours before refinement
- }
- void Morphology_Operations()
- {
- // Since MORPH_X : 2,3,4,5 and 6
- //Operator: 2: Opening 3: Closing 4: Gradient 5: Top Hat 6: Black Hat
- int operation = 2;
- Mat element = getStructuringElement(morph_elem, Size(2 * morph_size + 1, 2 * morph_size + 1), Point(morph_size, morph_size));
- /// Apply the specified morphology operation
- morphologyEx(invsrc, dst, operation, element);
- }
- //////////############################Zooming functions start here#################################/////////////////////////
- //Re-modeled function that provides the ability to zoom
- //in on pictures when they are displayed
- Mat zoomIn(int x, int y)
- {
- int width = zoomRec, height = zoomRec;
- int ptoX = x - (zoomRec / 2), ptoY = y - (zoomRec / 2);
- if ((x + (zoomRec / 2)) > imagen.size().width){
- width = width - ((x + (zoomRec / 2)) - imagen.size().width);
- }
- if ((y + (zoomRec / 2)) > imagen.size().height){
- height = height - ((y + (zoomRec / 2)) - imagen.size().height);
- }
- if ((x - (zoomRec / 2)) < 0){
- ptoX = 0;
- }
- if ((y - (zoomRec / 2)) < 0){
- ptoY = 0;
- }
- Rect roi = Rect(ptoX, ptoY, width, height);
- Mat imagen_roi = imagen(roi);
- resize(imagen_roi, imagen_roi, Size(imagenOriginal.size().width, imagenOriginal.size().height), 0, 0, CV_INTER_AREA);
- return imagen_roi;
- }
- //Returns original image
- Mat zoomOut(int x, int y)
- {
- return imagenOriginal;
- }
- //Mouse click event listener
- static void onMouse(int event, int x, int y, int /*flags*/, void* /*param*/)
- {
- mousex = x;
- mousey = y;
- if (event == CV_EVENT_LBUTTONDOWN)
- imagen = zoomIn(x, y);
- else if (event == CV_EVENT_RBUTTONDOWN)
- imagen = zoomOut(x, y);
- }
- //Zooming instructions output to the console
- void info(){
- cout << "Training machine learning:\n";
- cout << "------------------------------\n";
- cout << "\nInstructions: \n"
- "\tType \"quit\" to exit \n"
- "\tESC - Direct to console from picture \n "
- "\t + - Increases the zoom \n"
- "\t - - Decreases the zoom \n"
- "\tCLICK L - zoom \n"
- "\tCLICK R - Restores picture \n" << endl;
- }
- //Zooming main function
- void zoom(Mat argv)
- {
- imagenOriginal = argv;
- if (imagenOriginal.empty())
- cout << "[ERROR] Could not load the image\n" << endl;
- //Create window
- namedWindow("Press Esc when done analizing", CV_WINDOW_NORMAL);
- //Create event listener for mouse
- setMouseCallback("Press Esc when done analizing", onMouse, 0);
- //Make copies of original image
- imagenOriginal.copyTo(imagen);
- imagenOriginal.copyTo(imagenMostrar);
- //Zoom in on the contour
- if (last == false)
- imagen = zoomIn(pCen.x, pCen.y);
- bool once = false;
- for (;;)
- {
- //Done only once in the loop and not at the end
- if (once == false && last == false)
- {
- //Put picture in the foreground
- SetForegroundWindow(look);
- once = true;
- }
- if (imagen.empty())
- break;
- imagen.copyTo(imagenMostrar);
- //Draw rectangle the represents where you will zoom
- rectangle(imagenMostrar,
- Point(mousex - (zoomRec / 2), mousey - (zoomRec / 2)),
- Point(mousex + (zoomRec / 2), mousey + (zoomRec / 2)),
- cv::Scalar(0, 255, 0), 1, 8, 0);
- //Display image
- imshow("Press Esc when done analizing", imagenMostrar);
- //Get the window that shows the picture
- look = GetForegroundWindow();
- char c = (char)waitKey(10);
- //When Esc is pressed
- if (c == 27){
- system("cls");
- //Put console in the foreground
- SetForegroundWindow(console);
- SetFocus(console);
- //Output instructions
- info();
- break;
- }
- switch (c)
- {
- //Increase the zoom
- case '+':
- if (zoomRec < maxRec)
- zoomRec = zoomRec + 10;
- break;
- //Decrease the zoom
- case '-':
- if (zoomRec > 10)
- zoomRec = zoomRec - 10;
- break;
- default:
- ;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement