DOGEZ DOGEZ - 25 days ago
108 0

Using opencv to recognize a cat in a live image.

C++

Cat detection

#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>

cv::Mat frame;
cv::Mat hsv;

int MX, MY;

void onMouse(int Event, int x, int y, int flags, void* param){
    if(Event == 0) return;
    printf("( %d, %d) ",x,y);
    printf("The Event is : %d ",Event);
    printf("The flags is : %d ",flags);
    printf("value: (%d %d %d)\n",
           hsv.at<cv::Vec3b>(y, x)[0],
           hsv.at<cv::Vec3b>(y, x)[1],
           hsv.at<cv::Vec3b>(y, x)[2]);
    
    MX = x;
    MY = y;
}

unsigned char data[] = "R";

int SerialPort_Connection()
{
    int fd;
    struct termios options;
    fd = open("/dev/tty.wchusbserial1410", O_RDWR | O_NONBLOCK);
    if(fd == -1) {
        printf("Device cannot be opened.\n");
        return -1;
    }
    
    
    if (tcgetattr(fd, &options) < 0){
        printf("tcgetattr failed. errno: %d\r\n", errno);
        close(fd);
        return -1;
    }
    
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    // no flow control
    options.c_cflag &= ~CRTSCTS;
    options.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
    options.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
    
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
    options.c_oflag &= ~OPOST; // make raw
    
    // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
    options.c_cc[VMIN]  = 0;
    options.c_cc[VTIME] = 0;
    if(tcsetattr(fd, TCSAFLUSH, &options) < 0) {
        perror("init_serialport: Couldn't set term attributes");
        return -1;
    }
    
    return fd;
}

int main()
{
    
    int distance = 0;
    int fd;
    
    if((fd=SerialPort_Connection()) == -1) {
        //return -1;
    }
    
    cv::Mat r, r2, g, b, mask;
    cv::Mat firstFrame;
    bool firstframe = true;
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;
    cv::RNG rng(12345);
    
    //cv::VideoCapture cap(0);
    cv::VideoCapture cap;
    const std::string ip = "http://192.168.10.123:7060/video?x.mjpeg";
    if(!cap.open(ip)) {
        printf("GG\n");
    }
    cv::namedWindow("Webcam", 0);
    
    cv::setMouseCallback("Webcam", onMouse);
    if(!cap.isOpened())
    {
        return -1;
    }
    
    while(true)
    {
        if(!cap.read(frame))
            continue;
        cv::Mat src = cv::Mat(frame);
        
        cv::Mat gray;
        cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
        cv::GaussianBlur(gray, gray, CvSize(21, 21), 0);
        
        if(firstframe) {
            gray.copyTo(firstFrame);
            firstframe = false;
        }
        
        cv::Mat frameDelta;
        cv::Mat thresh;
        
        cv::absdiff(firstFrame, gray, frameDelta);
        cv::threshold(frameDelta, thresh, 128, 255, cv::THRESH_BINARY);
        cv::dilate(thresh, thresh, cv::Mat());
        cv::dilate(thresh, thresh, cv::Mat());
        cv::findContours(thresh, contours, hierarchy, CV_RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
        std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
        std::vector<cv::Rect> boundRect( contours.size() );
        std::vector<cv::Point2f>center( contours.size() );
        std::vector<float>radius( contours.size() );
        
        for( int i = 0; i < contours.size(); i++ )
        {
            if(cv::contourArea(contours[i]) < 10000)
                continue;
    
            boundRect[i] = boundingRect(contours[i]);
            rectangle(frame, boundRect[i].tl(), boundRect[i].br(), cv::Scalar(0, 0, 255), 2, 8, 0 );
        }
        
        
        cv::imshow("Security Feed", frame);
        cv::imshow("Thresh", thresh);
        cv::imshow("Frame Delta", frameDelta);
        cv::waitKey(30);
        
        continue;
        
        circle(frame, CvPoint( MX, MY ), 50, CvScalar( 0, 0, 255));
        cv::cvtColor(src, hsv, CV_BGR2HSV);
        
        
        inRange(hsv, cv::Scalar(8,170,220) , cv::Scalar(16, 255, 255), r);
        //inRange(hsv, cv::Scalar(0,60,100) , cv::Scalar(15, 140, 240), r);
        //inRange(hsv, cv::Scalar(10,100,120) , cv::Scalar(20, 200, 150), r);
        
        findContours(r, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE,
                     cv::Point(0, 0) );
        
        for( int i = 0; i < contours.size(); i++ )
        {
            approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 3, true );
            boundRect[i] = boundingRect( cv::Mat(contours_poly[i]) );
        }
        
        for( int i = 0; i< contours.size(); i++ )
        {
            if(boundRect[i].width < 40) continue;
            
            cv::Scalar color = cv::Scalar(0, 0, 255);
            
            rectangle(src, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
            
            //printf("(%d: %d, %d)\n", i, src.size[1]/2, boundRect[i].x + boundRect[i].width/2 - src.size[1]/2);
            distance = boundRect[i].x + boundRect[i].width/2 - src.size[1]/2;
            if(distance-100 > 0)
                write(fd, "L", 1);
            else if(distance+100 < 0)
                write(fd, "R", 1);
            else
                write(fd, "S", 1);
            break;
            
        }
    
        
        // CAT
        //inRange(hsv, cv::Scalar(0,10,20) , cv::Scalar(40, 230, 80), r);
        
        //mask=r+r2+g+b;//全部的二值化圖累加起來就變成遮罩
        
        //cv::cvtColor(src, hsv, CV_BGR2GRAY);
        //src.copyTo(hsv, r); //將原圖片經由遮罩過濾後,得到結果dst
        cv::imshow( "Webcam",  src);
        cv::waitKey(30);
        
    }
}