Пример #1
0
std::vector<cv::Point2f> ShapeFilter::findMassCenter(Data *data){
    // check for whether the input is of the correct type.          From Albert
    ImgData* imgData = dynamic_cast<ImgData*>(data);
    if (imgData == 0) {
        std::vector<cv::Point2f> bad;
        return bad;
    }
    return findMassCenter(imgData->getImg());
}
Пример #2
0
bool ShapeFilter::filter(Data *data){
    // check for whether the input is of the correct type.          From Albert
    ImgData* imgData = dynamic_cast<ImgData*>(data);
    if (imgData == 0) {
        // track the error and return error
        this->track(data,this->filterID,1,1);
        return false;
    }

   //beging filtering process
    if (shape == 1){        ///rectangle
        return this->findRect((imgData->getImg()));   //lazy to copy+paste everything
    }else if (shape == 2){  ///circle
        return this->findCirc(imgData->getImg());
    }
    //ending filtering process

    //track and return
    this->track(imgData, this->filterID, 0,0);
    return true;
}
Пример #3
0
bool LineFilter::filter(Data *data){
    // check for whether the input is of the correct type.          From Albert
    ImgData* imgData = dynamic_cast<ImgData*>(data);
    if (imgData == 0) {
        // track the error and return error
        this->track(data,this->filterID,1,1);
        return false;
    }
    cv::imshow("asdf", filter(imgData->getImg().clone(),0));

    //begin filter sequence
    int linesFound = 0;
    cv::Mat src = imgData->getImg();
    cv::Mat dst;
    cv::Mat cdst = src.clone();
    Canny(src, dst, 50, 200, 3);
    cvtColor(dst, cdst, CV_GRAY2BGR);

    std::vector<cv::Vec2f> lines;
    //detects lines
    HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
    //ending filter sequence

    //calculating the line equation
    linesEq.clear();
    float x1 = 0, x2 = 0, y1 = 0, y2 = 0;
    for( size_t i = 0; i < lines.size(); i++ ){
        float rho = lines[i][0], theta = lines[i][1];
        cv::Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));

        x1 = pt1.x;
        y1 = pt1.y;
        x2 = pt2.x;
        y2 = pt2.y;
        //equation of line
        std::vector<float> eq;

        //y = mx+b
        //B MIGHT BE USELSES, NEED FURTHER TESTING
        bool safeMath = true;
        float M = 0, B = 0;
        if (x2-x1 < 5){     //straight line
            safeMath = false;
            M = INFINITY;
            B = INFINITY;
        }
        if (safeMath){      //avoid div by 0 error
            //M = (y2-y1) / (x2-x1);
            double realtheta = (rho < 0)? theta - M_PI:theta;
            realtheta = -realtheta +  M_PI/2;
            M = tan(realtheta);
            B = y2 - M*x2;
        }

        bool repeat = false;
        //check if there is a similar line already
        for (std::vector<float> lines: linesEq){
            //vert line situations
            if (M == INFINITY && lines[0] == INFINITY){
                //check their x values
                if (std::abs(lines[2] - ((x1+x2)/2)) < maxDiff){
                    repeat = true;
                    break;
                }
            }
            //check if m is almost vertical
            else if (std::abs(M) > maxSlope && lines[0] == INFINITY){
                //std::cout<<"almost vert ";
                //std::cout<<std::abs(lines[2] - ((x1+x2)/2))<<std::endl;
                if (std::abs(lines[2] - ((x1+x2)/2) ) < maxDiff){
                    repeat = true;
                    break;
                }
            }
            else if (M == INFINITY && std::abs(lines[0])> maxSlope){
                //std::cout<<"almost vert II ";
                //std::cout<<std::abs(lines[2] - ((x1+x2)/2))<<std::endl;
                if (std::abs(lines[2] - ((x1+x2)/2) ) < maxDiff){
                    repeat = true;
                    break;
                }
            }
            //check if m is too similar or not, b is too different to check
            else if (std::abs(lines[0] - M) < maxDiff){
                if (M > 15){ //vertical lines
                    //check if the intersection point is near the average x
                    if (std::abs((B-lines[1])/(lines[0]-M))-(x1+x2)/2 < maxDiff){
                        repeat = true;
                        break;
                    }
                }else{      //horziontal lines
                    if (std::abs((B-lines[1])/(lines[0]-M))*M - (y1+y2)/2 < maxDiff){
                        repeat = true;
                        break;
                    }
                }
            }
        }

        if (!repeat){
            eq.push_back(M);
            eq.push_back(B);
            //std::cout<<M<<" "<<B<<" " << ((x1+x2)/2) << " ";
            if (std::abs(M) < 5){  //aprox horizontal line
                eq.push_back(y2);   //give it the y value
                //std::cout<<y2;
                //printf(" horz line");
            }
            if (std::abs(M) > maxSlope){ //vertical line
                eq.push_back(x2);   //x value
                //std::cout<<x2;
                //printf(" vertal line");
            }
            //std::cout<<std::endl;

            linesEq.push_back(eq);
            linesFound++;
            //line(*cdst, pt1, pt2, cv::Scalar(0,0,255), 3, CV_AA);     //drawing the line
        }
    }

    //should i set imgData to something?? -Carl

    //track and return
    this->track(imgData, this->filterID, 0,0);
    //println(linesFound != 0);
    return linesFound != 0;
}
Пример #4
0
void BuoyTask::execute() {

    HSVFilter green(std::stoi(settings->getProperty("g1")),
                    std::stoi(settings->getProperty("g2")),
                    std::stoi(settings->getProperty("g3")),
                    std::stoi(settings->getProperty("g4")),
                    std::stoi(settings->getProperty("g5")),
                    std::stoi(settings->getProperty("g6")));

    HSVFilter red(std::stoi(settings->getProperty("r1")),
                  std::stoi(settings->getProperty("r2")),
                  std::stoi(settings->getProperty("r3")),
                  std::stoi(settings->getProperty("r4")),
                  std::stoi(settings->getProperty("r5")),
                  std::stoi(settings->getProperty("r6")));
    //only look for 1 circle
    ShapeFilter sf (2, 1);

    //assuming the sub is in the correct position
    //first look for red, and then hit it
    //then look and hit green

    bool hitGreen = false;
    bool hitRed = false;

    int retreat = 0;
    int moveDist = std::stoi(settings->getProperty("moveDist"));
    int rotateAng = std::stoi(settings->getProperty("rotateAng"));
    int movementDelay = std::stoi(settings->getProperty("movementDelay"));
    int deltaDist = 0;
    float deltaT = 0;

    bool done = false;

    while (!done) {
        std::string s = "raw";
        ImgData* data = dynamic_cast<ImgData*>
                (dynamic_cast<CameraState*>
                 (camModel->getState())->getDeepState(s));
        imgWidth = data->getImg().size().width;
        imgHeight = data->getImg().size().height;
//        cv::imshow("hsv",data->getImg());

        //filter for a color depending if the other color is hit or not
        if (!hitRed){
            println("Filtering red");
            red.filter(data);
        } else if (!hitGreen){
            //println("Filtering green");
            //green.filter(data);
            done = true;
            continue;
        } else if (hitGreen && hitRed) {
            done = true;
            println("Done task");
            continue;
        }

        //after hitting a color, move the sub back to look for the other one
        //TODO: CALIBRATE THIS STEP

        if (sf.filter(data)){
            retreat = false;
            cv::Point2f cent = sf.getCenter()[0];
            if (std::abs(cent.x - imgWidth/2) < imgWidth/20){
                //in the middle 20% of the screen horizontally
                if (std::abs(cent.y - imgHeight / 2) < imgHeight / 20) {
                    //in the middle 20% vertically
                    float d = calcDistance(sf.getRad()[0]) * 1.2;
                    float t = d/moveSpeed;
                    println("Moving " + std::to_string(d) + "cm in " + std::to_string(t) + "s");
                    move(moveSpeed);
                    usleep(std::stoi(settings->getProperty("MOVE_TIME")));
                    if (!hitRed){
                        hitRed = true;
                        println("Hit red");
                        retreat = true;
                    } else {
                        hitGreen = true;
                        println("Hit green");
                        retreat = true;
                    }
                    logger->info("Stopping");
                    move(0);
                    /*
                    //if the radius of the circle is huge, so the sub will hit it
                    if (sf.getRad()[0] > imgWidth*imgHeight/3){
                        if (!hitGreen){
                            hitGreen = true;
                            println("Hit green");
                        }else{
                            hitRed = true;
                            println("Hit red");
                        }

                        //return the sub back to its orginal position
                        move(0);
                        retreat = true;
                        println("Retreat enabled");
                    }else{
                        //move straight and hit it
                        float dist = calcDistance(sf.getRad()[0]);
                        deltaDist = dist*1.2;
                        println("Moving forward " + std::to_string(deltaDist) + "cm to hit buoy");
                        move(deltaDist);
                    }*/
                } else {
                    float deltaY;
                    if (cent.y > imgHeight/2) {
                        deltaY = -0.1; //rise a bit
                    } else {
                        deltaY = 0.1; //sink a bit
                    }
                    //float deltaY = (cent.y - imgHeight/2)/sf.getRad()[0];
                    println("Rising " + std::to_string(deltaY*100)+"cm");
                    changeDepth(deltaY);
                }
            } else {
                println("Center: " + std::to_string(cent.x) + " " + std::to_string(imgWidth/2));
                //float ang = atan2(cent.x-imgWidth/2, 0) * 180 / M_PI;
                //float dX = cent.x-imgWidth/2;
                //dX * 23/sf.getRad()[0];
                //float ang = atan(dX/calcDistance(sf.getRad()[0])) * 180 / M_PI;
                //println("Rotating " + std::to_string(ang) + " degrees");
                //rotate(ang);
                float dir = cent.x-imgWidth/2;
                println("Rotating 10 degrees " + std::to_string(dir));
                dir /= std::abs(dir);
                rotate (5*dir);
                /*
                float scale = 23/sf.getRad()[0];
                float dist = sf.getCenter()[0].x - imgWidth/2;

                //slide 2/3 of the way
                float deltaX = dist*scale/3*2;
                println("Sliding " + std::to_string(deltaX)+"cm");
                slide(deltaX);*/
            }
        } else {
            ///CIRCLES NOT FOUND
            ///ROTATE/MOVE SUB
            //rotate(rotateAng);
            println("Circle not found, moving forward");
            //move(moveDist);
            if (retreat) {
                if (moveWithSpeed){
                    println("Retreating");
                    move(-moveSpeed);
                    usleep(40000000);
                    //usleep(deltaT * 500);
                    move(0);
                    rotate(-deltaAngle);
                    usleep(5000000);
                } else {
                    println("Retreating " + std::to_string(-deltaDist - 20) + "cm");
                    move(-deltaDist - 20);      //move 20cm more than i needed

                    //sleep(movementDelay);
                    //move the sub back to the middle
                    if (deltaAngle != -1){
                        println("Retreat rotating " + std::to_string(deltaAngle) + " degrees");
                        rotate(deltaAngle);
                        println("Retreat to middle by " + std::to_string(deltaDist-20) + "cm");
                        move (deltaDist-20);   //move 20cm less than i need
                        rotate(-deltaAngle);
                    }
                }
                retreat = false;
//                continue;
            } else {
                ///tries to look for any colors and move towards it
                logger->info("Looking for coloured masses to turn towards");
                std::vector<cv::Point2f> mc = sf.findMassCenter(data);
                if (mc.size() > 0) {
                    logger->info("Found coloured mass");
                    float dir = mc[0].x - imgWidth/2;
                    dir /= std::abs(dir);
                    rotate(5 * dir);
                } else {
                    ///if it dosnt see any colors, move forwards
                    logger->debug("No coloured masses found.  Moving forward");
                    move(moveSpeed);
                }
            }
        }
        delete data;
        data = 0;
        usleep(33000);
    }
}
Пример #5
0
bool RGBFilter::filter(Data* data) {
	// check for whether the input is of the correct type.
	ImgData* cast = dynamic_cast<ImgData*>(data);
	if (cast == 0) {
		// track the error and return error
		this->track(data,this->filterID,1,1);
        return false;
	}

    if (cast->img.type() != 16) {
		this->track(data,this->filterID,2,1);
        return false;
	}

	// begin filter sequence.
	int newPixelVal;
    cv::Mat src = cast->getImg();
    cv::Mat filteredImg = src.clone();
	cv::Mat BGR[3];

	cv::split(filteredImg,BGR);
	// catch error?

	// Full spectrum mode
	if(this->mode == 0) {
        for(int y = 0; y < src.cols; y++ ) {
            for(int x = 0; x < src.rows; x++ ) {
				for(int c = 0; c < 3; c++) {
                    newPixelVal = std::max(0,std::min(mxColour,BGR[c].at<unsigned char>(x,y) + midMult[c]*midtone[c]));
					BGR[c].at<unsigned char>(x,y) = newPixelVal;
				}
			}
		}
	}

	// 3 zone mode
	if (this->mode == 1) {
		int luminosity;
        const int SHADTHRESHOLD = (int) mxColour*10/3;
		const int HIGHTHRESHOLD = SHADTHRESHOLD * 2;
		// get luminosity with some function
		// use luminosity as a switch for case using high, mid or shad
        for(int y = 0; y < src.cols; y++ ) {
            for(int x = 0; x < src.rows; x++ ) {
				// From 11%,59%,30% bgr respectively. Scaled to 1:6:3 factors
				// luminosity range is from 0-2550, 1/3 is 850. Calc this from:
				// 10*255, 10* MXCOLOR
				luminosity = BGR[0].at<unsigned char>(x,y)*1+BGR[1].at<unsigned char>(x,y)*6+BGR[2].at<unsigned char>(x,y)*3;

				for(int c = 0; c < 3; c++) {

					if (luminosity < SHADTHRESHOLD)
                        newPixelVal = std::max(0,std::min(mxColour,BGR[c].at<unsigned char>(x,y) + shadMult[c]*shadow[c]));
					else if (luminosity > HIGHTHRESHOLD)
                        newPixelVal = std::max(0,std::min(mxColour,BGR[c].at<unsigned char>(x,y) + highMult[c]*highlight[c]));
					else
                        newPixelVal = std::max(0,std::min(mxColour,BGR[c].at<unsigned char>(x,y) + midMult[c]*midtone[c]));

					BGR[c].at<unsigned char>(x,y) = newPixelVal;
				}
			}
		}
	}

	//joining seq
	cv::merge(BGR,3,filteredImg);

	//set sequence
    cast->setImg(filteredImg);

	// end sequence.

	// track and return
	this->track(cast,this->filterID,0,0);
    return true;
}