/* decode ubx-nav-clk: navigation clock -----------------------------------*/ int decode_navclock(tUbxRawData *raw) { UbxMsg01_22_CLK clk; unsigned char *p = raw->buff + UBX_MSGSTART_SHIFT; memset(&clk, 0, sizeof(clk)); clk.iTOW = U4(p); clk.clkBias = I4(p + 4); clk.clkDrift = I4(p + 8); clk.unc_clkBias = U4(p + 12); clk.unc_clkDrift = U4(p + 16); /* fill up interface for real time processing */ pb_Set_ExternalUbxGNSS_CLK(&clk); return 0; }
int decode_navgpstime(tUbxRawData *raw) { unsigned char *p = raw->buff + UBX_MSGSTART_SHIFT; tExternalGNSSGPSTimePtr gpstime = Msg_Get_ExternalGnssGpsTime(); /* do not reset this struct due to week and leapsecond */ gpstime->iTow = U4(p); gpstime->fTow = I4(p+4); gpstime->gpsWeek = (short)(I2(p + 8)); gpstime->leapSec = (short)(I1(p + 10)); return 0; }
/* decode NVS x4btime --------------------------------------------------------*/ static int decode_x4btime(raw_t *raw) { unsigned char *p=raw->buff+2; trace(4,"decode_x4btime: len=%d\n", raw->len); raw->nav.utc_gps[1] = R8(p ); raw->nav.utc_gps[0] = R8(p+ 8); raw->nav.utc_gps[2] = I4(p+16); raw->nav.utc_gps[3] = I2(p+20); raw->nav.leaps = I1(p+22); return 9; }
"0;\n" "1234;\n" "}\n"; static char object_syntax_semicolon_txt[] = "xof 0302txt 0064\n" "Buffer\n" "{\n" "3;\n" "0; 1; 2;\n" "5;\n" "}\n"; static char object_syntax_semicolon_bin[] = { 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4', TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE, TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON, TOKEN_INTEGER, I4(0), TOKEN_SEMICOLON, TOKEN_INTEGER, I4(1), TOKEN_SEMICOLON, TOKEN_INTEGER, I4(2), TOKEN_SEMICOLON, TOKEN_INTEGER, I4(5), TOKEN_SEMICOLON, TOKEN_CBRACE }; static char object_syntax_comma_txt[] = "xof 0302txt 0064\n" "Buffer\n" "{\n" "3,\n" "0, 1, 2,\n" "5,\n" "}\n";
void Scaler::ScaleBilinearFP(intType fromRow, int32 toRow) { BBitmap* src; BBitmap* dest; intType srcW, srcH; intType destW, destH; intType x, y, i; ColumnDataFP* columnData; ColumnDataFP* cd; const uchar* srcBits; uchar* destBits; intType srcBPR, destBPR; const uchar* srcData; uchar* destDataRow; uchar* destData; const int32 kBPP = 4; src = GetSrcImage(); dest = fScaledImage; srcW = src->Bounds().IntegerWidth(); srcH = src->Bounds().IntegerHeight(); destW = dest->Bounds().IntegerWidth(); destH = dest->Bounds().IntegerHeight(); srcBits = (uchar*)src->Bits(); destBits = (uchar*)dest->Bits(); srcBPR = src->BytesPerRow(); destBPR = dest->BytesPerRow(); fixed_point fpSrcW = to_fixed_point(srcW); fixed_point fpDestW = to_fixed_point(destW); fixed_point fpSrcH = to_fixed_point(srcH); fixed_point fpDestH = to_fixed_point(destH); columnData = new ColumnDataFP[destW]; cd = columnData; for (i = 0; i < destW; i ++, cd++) { fixed_point column = to_fixed_point(i) * (long_fixed_point)fpSrcW / fpDestW; cd->srcColumn = from_fixed_point(column); cd->alpha1 = tail_value(column); // weigth for left pixel value cd->alpha0 = kFPOne - cd->alpha1; // weigth for right pixel value } destDataRow = destBits + fromRow * destBPR; for (y = fromRow; IsRunning() && y <= toRow; y ++, destDataRow += destBPR) { fixed_point row; intType srcRow; fixed_point alpha0, alpha1; if (fpDestH == 0) { row = 0; } else { row = to_fixed_point(y) * (long_fixed_point)fpSrcH / fpDestH; } srcRow = from_fixed_point(row); alpha1 = tail_value(row); // weight for row y+1 alpha0 = kFPOne - alpha1; // weight for row y srcData = srcBits + srcRow * srcBPR; destData = destDataRow; // Need mult_correction for "outer" multiplication only #define I4(i) from_fixed_point(mult_correction(\ (a[i] * a0 + b[i] * a1) * alpha0 + \ (c[i] * a0 + d[i] * a1) * alpha1)) #define V2(i) from_fixed_point(a[i] * alpha0 + c[i] * alpha1); #define H2(i) from_fixed_point(a[i] * a0 + b[i] * a1); if (y < destH) { fixed_point a0, a1; const uchar *a, *b, *c, *d; for (x = 0; x < destW; x ++, destData += kBPP) { a = srcData + columnData[x].srcColumn * kBPP; b = a + kBPP; c = a + srcBPR; d = c + kBPP; a0 = columnData[x].alpha0; a1 = columnData[x].alpha1; destData[0] = I4(0); destData[1] = I4(1); destData[2] = I4(2); destData[3] = I4(3); } // right column a = srcData + srcW * kBPP; c = a + srcBPR; destData[0] = V2(0); destData[1] = V2(1); destData[2] = V2(2); destData[3] = V2(3); } else { fixed_point a0, a1; const uchar *a, *b; for (x = 0; x < destW; x ++, destData += kBPP) { a = srcData + columnData[x].srcColumn * kBPP; b = a + kBPP; a0 = columnData[x].alpha0; a1 = columnData[x].alpha1; destData[0] = H2(0); destData[1] = H2(1); destData[2] = H2(2); destData[3] = H2(3); } // bottom, right pixel a = srcData + srcW * kBPP; destData[0] = a[0]; destData[1] = a[1]; destData[2] = a[2]; destData[3] = a[3]; } } delete[] columnData; }
void imageCallback(const sensor_msgs::ImageConstPtr& msg) { //bridge that will transform the message (image) from ROS code back to "image" code sensor_msgs::CvBridge bridge; fprintf(stderr, "\n callBaack funtion \n"); //publish data (obstacle waypoints) back to the boat ros::NodeHandle n; //std_msgs::Float32 xWaypoint_msg; // X coordinate obstacle message //std_msgs::Float32 yWaypoint_msg; // Y coordinate obstacle message //publish the waypoint data //ros::Publisher waypoint_info_pub = n.advertise<std_msgs::Float32>("waypoint_info", 1000); //ros::Publisher Ywaypoint_info_pub = n.advertise<std_msgs::Float32>("waypoint_info", 1000); //std::stringstream ss; /***********************************************************************/ //live image coming streamed straight from the boat's camera IplImage* boatFront = bridge.imgMsgToCv(msg, "bgr8"); IplImage* backUpImage = bridge.imgMsgToCv(msg, "bgr8"); boatFront->origin = IPL_ORIGIN_TL; //sets image origin to top left corner //Crop the image to the ROI cvSetImageROI(boatFront, cvRect(0,0,boatFront->height/0.5,boatFront->width/1.83)); int X = boatFront->height; int Y = boatFront->width; /***********************************************************************/ //boat's edge distance from the camera. This is used for visual calibration //to know the distance from the boat to the nearest obstacles. //With respect to the mounted camera, distance is 21 inches (0.5334 m) side to side //and 15 inches (0.381 m). //float boatFrontDistance = 0.381; //distance in meters //float boatSideDistance = 0.5334; //distance in meters // These variables tell the distance from the center bottom of the image // (the camera) to the square surrounding a the obstacle float xObstacleDistance = 0.0; float yObstacleDistance = 0.0; float obstacleDistance = 0.0; int pixelsNumber = 6; //number of pixels for an n x n matrix and # of neighbors const int arraySize = pixelsNumber; const int threeArraySize = pixelsNumber; //if n gets changed, then the algorithm might have to be //recalibrated. Try to keep it constant //these variables are used for the k nearest neighbors //int accuracy; //reponses for each of the classifications float responseWaterH, responseWaterS, responseWaterV; float responseGroundH, responseGroundS, responseGroundV; //float responseSkyH, responseSkyS, responseSkyV; float averageHue = 0.0; float averageSat = 0.0; float averageVal = 0.0; CvMat* trainClasses = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); CvMat* trainClasses2 = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); for (int i = 0; i < pixelsNumber/2; i++) { cvmSet(trainClasses, i,0,1); cvmSet(trainClasses2, i,0,1); } for (int i = pixelsNumber/2; i < pixelsNumber; i++) { cvmSet(trainClasses, i,0,2); cvmSet(trainClasses2, i,0,2); } //for (int i =0; i<pixelsNumber;i++) //{ // cout << cvmGet(trainClasses,i,0); // cout << cvmGet(trainClasses2,i,0); //} //CvMat sample = cvMat( 1, 2, CV_32FC1, _sample ); //used with the classifier CvMat* nearestWaterH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestWaterS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestWaterV = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestGroundH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestGroundS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestGroundV = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* nearestSkyH = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* nearestSkyS = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* nearestSkyV = cvCreateMat(1, pixelsNumber, CV_32FC1); //Distance //CvMat* distanceWaterH = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceWaterS = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceWaterV = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceGroundH = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceGroundS = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceGroundV = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceSkyH = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceSkyS = cvCreateMat(1, pixelsNumber, CV_32FC1); //CvMat* distanceSkyV = cvCreateMat(1, pixelsNumber, CV_32FC1); //these variables are use to traverse the picture by blocks of n x n pixels at //a time. //Index(0,0) does not exist, so make sure kj and ki start from 1 (in the //right way, of course) //x and y are the dimensions of the local patch of pixels int x = (boatFront->height)/2.5 + pixelsNumber + 99; int y = pixelsNumber-1; int ix = 0; int iy = 0; int skyX = 0; int skyY = 0; //M controls the x axis (up and down); N controls the y axis (left and //right) int Mw = -550; int Nw = 1300; int Mg = -350; int Ng = 700; int row1 = 0; int column1 = 0; int row2 = 0; int column2 = 0; //ground sample CvMat* groundTrainingHue = cvCreateMat(threeArraySize,arraySize,CV_32FC1); CvMat* groundTrainingSat = cvCreateMat(threeArraySize,arraySize,CV_32FC1); CvMat* groundTrainingVal = cvCreateMat(threeArraySize,arraySize,CV_32FC1); //water sample CvMat* waterTrainingHue = cvCreateMat(threeArraySize,arraySize,CV_32FC1); CvMat* waterTrainingSat = cvCreateMat(threeArraySize,arraySize,CV_32FC1); CvMat* waterTrainingVal = cvCreateMat(threeArraySize,arraySize,CV_32FC1); //n x n sample patch taken from the picture CvMat* sampleHue = cvCreateMat(1,arraySize,CV_32FC1); CvMat* sampleSat = cvCreateMat(1,arraySize,CV_32FC1); CvMat* sampleVal = cvCreateMat(1,arraySize,CV_32FC1); CvMat* resampleHue = cvCreateMat(arraySize,arraySize,CV_32FC1); CvMat* resampleSat = cvCreateMat(arraySize,arraySize,CV_32FC1); CvMat* resampleVal = cvCreateMat(arraySize,arraySize,CV_32FC1); //sky training sample CvMat* skyTrainingHue = cvCreateMat(arraySize,arraySize,CV_32FC1); CvMat* skyTrainingSat = cvCreateMat(arraySize,arraySize,CV_32FC1); CvMat* skyTrainingVal = cvCreateMat(arraySize,arraySize,CV_32FC1); //initialize each matrix element to zero for ease of use cvZero(groundTrainingHue); cvZero(groundTrainingSat); cvZero(groundTrainingVal); cvZero(waterTrainingHue); cvZero(waterTrainingSat); cvZero(waterTrainingVal); cvZero(sampleHue); cvZero(sampleSat); cvZero(sampleVal); cvZero(resampleHue); cvZero(resampleSat); cvZero(resampleVal); cvZero(skyTrainingHue); cvZero(skyTrainingSat); cvZero(skyTrainingVal); //Stores the votes for each channel (whether it belongs to water or not //1 is part of water, 0 not part of water //if sum of votes is bigger than 1/2 the number of elements, then it belongs to water int votesSum = 0; int comparator[3]; //used when only three votes are needed //int comparatorTwo [3][3]; //used when six votes are needed //initial sum of votes is zero //Error if initialize both matrices inside a single for loop. Dont know why // for(int i = 0; i < 3; i++) //{ //comparator[i] = 0; // for(int j = 0; j < 3; j++) // { // comparatorTwo[i][j] = 0; // } //} for(int i = 0; i < 3; i++) { comparator[i] = 0; } /***********************************************************************/ //Convert from RGB to HSV to control the brightness of the objects. //work with reflexion /*Sky recognition. Might be useful for detecting reflexion on the water. If the sky is detected, and the reflection has the same characteristics of something below the horizon, that "something" might be water. Assume sky wont go below the horizon*/ //convert from RGB to HSV cvCvtColor(boatFront, boatFront, CV_BGR2HSV); cvCvtColor(backUpImage, backUpImage, CV_BGR2HSV); HsvImage I(boatFront); HsvImage IBackUp(backUpImage); fprintf(stderr,"\n About to do Sky detection\n"); //Sky detection for (int i=0; i<boatFront->height/3;i++) { for (int j=0; j<boatFront->width;j++) { //if something is bright enough, consider it sky and store the //value. HSV values go from 0 to 180 ... RGB goes from 0 to 255 if (((I[i][j].v >= 180) && (I[i][j].s <= 16))) // && ((I[i][j].h >=10)))) //&& (I[i][j].h <= 144)))) { //The HSV values vary between 0 and 1 cvmSet(skyTrainingHue,skyX,skyY,I[i][j].h); cvmSet(skyTrainingSat,skyX,skyY,I[i][j].s); cvmSet(skyTrainingVal,skyX,skyY,I[i][j].v); I[i][j].h = 0.3*180; //H (color) I[i][j].s = 0.3*180; //S (color intensity) I[i][j].v = 0.6*180; //V (brightness) if (skyY == pixelsNumber-1) { if (skyX == pixelsNumber-1) skyX = 1; else skyX = skyX + 1; skyY = 1; } else skyY = skyY + 1; } } } /***********************************************************************/ //offline input pictures. Samples of water properties are taken from these //pictures to get a range of values for H, S, V that will be stored into a //pre-defined classifier IplImage* imageSample1 = cvLoadImage("bigObstacle.jpg"); cvSetImageROI(imageSample1, cvRect(0,0,imageSample1->height/0.5,imageSample1->width/1.83)); cvCvtColor(imageSample1, imageSample1, CV_BGR2HSV); HsvImage I1(imageSample1); IplImage* imageSample2 = cvLoadImage("bigObstacle2.jpg"); cvSetImageROI(imageSample2, cvRect(0,0,imageSample2->height/0.5,imageSample2->width/1.83)); cvCvtColor(imageSample2, imageSample2, CV_BGR2HSV); HsvImage I2(imageSample2); IplImage* imageSample3 = cvLoadImage("bigObstacle3.jpg"); cvSetImageROI(imageSample3, cvRect(0,0,imageSample3->height/0.5,imageSample3->width/1.83)); cvCvtColor(imageSample3, imageSample3, CV_BGR2HSV); HsvImage I3(imageSample3); IplImage* imageSample4 = cvLoadImage("river.jpg"); cvSetImageROI(imageSample4, cvRect(0,0,imageSample4->height/0.5,imageSample4->width/1.83)); cvCvtColor(imageSample4, imageSample4, CV_BGR2HSV); HsvImage I4(imageSample4); IplImage* imageSample5 = cvLoadImage("river2.jpg"); cvSetImageROI(imageSample5, cvRect(0,0,imageSample5->height/0.5,imageSample5->width/1.83)); cvCvtColor(imageSample5, imageSample5, CV_BGR2HSV); HsvImage I5(imageSample5); IplImage* imageSample6 = cvLoadImage("roundObstacle4.jpg"); cvSetImageROI(imageSample6, cvRect(0,0,imageSample6->height/0.5,imageSample6->width/1.83)); cvCvtColor(imageSample6, imageSample6, CV_BGR2HSV); HsvImage I6(imageSample6); IplImage* imageSample7 = cvLoadImage("farm.jpg"); cvSetImageROI(imageSample7, cvRect(0,0,imageSample7->height/0.5,imageSample7->width/1.83)); cvCvtColor(imageSample7, imageSample7, CV_BGR2HSV); HsvImage I7(imageSample7); IplImage* imageSample8 = cvLoadImage("bigObstacle4.jpg"); cvSetImageROI(imageSample8, cvRect(0,0,imageSample8->height/0.5,imageSample8->width/1.83)); cvCvtColor(imageSample8, imageSample8, CV_BGR2HSV); HsvImage I8(imageSample8); IplImage* imageSample9 = cvLoadImage("roundObstacle6.jpg"); cvSetImageROI(imageSample9, cvRect(0,0,imageSample9->height/0.5,imageSample9->width/1.83)); cvCvtColor(imageSample9, imageSample9, CV_BGR2HSV); HsvImage I9(imageSample9); IplImage* imageSample10 = cvLoadImage("roundObstacle.jpg"); cvSetImageROI(imageSample10, cvRect(0,0,imageSample10->height/0.5,imageSample10->width/1.83)); cvCvtColor(imageSample10, imageSample10, CV_BGR2HSV); HsvImage I10(imageSample10); fprintf(stderr,"\n Grab water samples\n"); //grab water samples from each picture for (int i=0; i < threeArraySize; i++) { fprintf(stderr,"\n patch is pink (this is for me to know where the ground patch sample is\n"); for (int j=0; j < arraySize; j++) { row1 = ceil(X/1.2866)+ceil(X/5.237)+i+Mw; row1 = x + i; if (row1 > X-1) row1 = X-1; column1 = ceil(Y/7.0755)+ceil(Y/21.01622)+j+Nw; if (column1 > Y-1) column1 = Y-1; averageHue = (I1[row1][column1].h + I2[row1][column1].h + I3[row1][column1].h + I4[row1][column1].h + I5[row1][column1].h + I6[row1][column1].h + I7[row1][column1].h + I8[row1][column1].h + I9[row1][column1].h + I10[row1][column1].h) / 10; averageSat = (I1[row1][column1].s + I2[row1][column1].s + I3[row1][column1].s + I4[row1][column1].s + I5[row1][column1].s + I6[row1][column1].s + I7[row1][column1].s + I8[row1][column1].s + I9[row1][column1].s + I10[row1][column1].s) / 10; averageVal = (I1[row1][column1].v + I2[row1][column1].v + I3[row1][column1].v + I4[row1][column1].v + I5[row1][column1].v + I6[row1][column1].v + I7[row1][column1].v + I8[row1][column1].v + I9[row1][column1].v + I10[row1][column1].v) / 10; fprintf(stderr,"\n water patch sample (n X n matrix)\n"); cvmSet(waterTrainingHue,i,j,averageHue); cvmSet(waterTrainingSat,i,j,averageSat); cvmSet(waterTrainingVal,i,j,averageVal); fprintf(stderr,"\n patch is red (this is for me to know where the ground patch sample is\n"); //I[row1][column1].h = 0; //I[row1][column1].s = 255; //I[row1][column1].v = 255; } } fprintf(stderr,"\n Order water samples in ascending\n"); //order the water samples in ascending order on order to know a range cvSort(waterTrainingHue, waterTrainingHue, CV_SORT_ASCENDING); cvSort(waterTrainingSat, waterTrainingSat, CV_SORT_ASCENDING); cvSort(waterTrainingVal, waterTrainingVal, CV_SORT_ASCENDING); // find the maximum and minimum values in the array to create a range int maxH = cvmGet(waterTrainingHue,0,0); int maxS = cvmGet(waterTrainingSat,0,0); int maxV = cvmGet(waterTrainingVal,0,0); int minH = cvmGet(waterTrainingHue,0,0); int minS = cvmGet(waterTrainingSat,0,0); int minV = cvmGet(waterTrainingVal,0,0); for (int i=0; i < threeArraySize; i++) { for (int j=0; j < arraySize; j++) { if (cvmGet(waterTrainingHue,i,j) > maxH) maxH = cvmGet(waterTrainingHue,i,j); if (cvmGet(waterTrainingSat,i,j) > maxS) maxS = cvmGet(waterTrainingHue,i,j); if (cvmGet(waterTrainingVal,i,j) > maxV) maxV = cvmGet(waterTrainingVal,i,j); if (cvmGet(waterTrainingHue,i,j) < minH) minH = cvmGet(waterTrainingHue,i,j); if (cvmGet(waterTrainingSat,i,j) < minS) minS = cvmGet(waterTrainingSat,i,j); if (cvmGet(waterTrainingVal,i,j) < minV) minV = cvmGet(waterTrainingVal,i,j); } } /***********************************************************************/ //Grab a random patch of water below the horizon and compare every other //pixel against it //The results of the water detection depend on where in the picture the //training samples are located. Maybe adding more training samples will //help improve this? fprintf(stderr,"\n Random patch\n"); /*for (int i=0; i < threeArraySize; i++) { for (int j=0; j < arraySize; j++) { row2 = ceil(X/4.7291)+ceil(X/8.3176)+i+Mg; column2 = ceil(Y/7.78378)+ceil(Y/16.54468)+j+Ng; //ground patch sample (n X n matrix) //Detecting the horizon in the picture might be an excellent visual aid to //choose where (above the horizon) you can take a ground training(1:3*n,1:n)g sample //from. The ground pixel sample can be at a constant distance from the //horizon cvmSet(groundTrainingHue,i,j,I[row2][column2].h); cvmSet(groundTrainingSat,i,j,I[row2][column2].s); cvmSet(groundTrainingVal,i,j,I[row2][column2].v); //patch is red (this is for me to know where the ground patch sample is) I[row2][column2].h = 60; I[row2][column2].s = 180; I[row2][column2].v = 90; } } //order the water samples in ascending order on order to know a range cvSort(groundTrainingHue, groundTrainingHue, CV_SORT_ASCENDING); cvSort(groundTrainingSat, groundTrainingSat, CV_SORT_ASCENDING); cvSort(groundTrainingVal, groundTrainingVal, CV_SORT_ASCENDING); */ // Main loop. It traverses through the picture //skyX = 0; //skyY = 0; //The distance formula calculated by plotting points is given by: /*********** distance = 0.0006994144*(1.011716711^x) *****************/ //cout << "Distance: " << distancePixels << endl; while (x < boatFront->height/1.158) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i<pixelsNumber;i++) { cvmSet(sampleHue,0,i,I[x][y].h); cvmSet(sampleSat,0,i,I[x][y].s); cvmSet(sampleVal,0,i,I[x][y].v); } //Find the shortest distance between a pixel and the neighbors from each of //the training samples (sort of inefficient, but might do the job...sometimes) //if (ix == pixelsNumber-1) //{ //HSV for water sample // learn classifier //CvKNearest knn(trainData, trainClasses, 0, false, itemsNumber); //CvKNearest knnWaterHue(waterTrainingHue, trainClasses, 0, false, pixelsNumber); //CvKNearest knnWaterSat(waterTrainingSat, trainClasses, 0, false, pixelsNumber); //CvKNearest knnWaterVal(waterTrainingVal, trainClasses, 0, false, pixelsNumber); //HSV for ground sample //CvKNearest knnGroundHue(groundTrainingHue, trainClasses2, 0, false, pixelsNumber); //CvKNearest knnGroundSat(groundTrainingSat, trainClasses2, 0, false, pixelsNumber); //CvKNearest knnGroundVal(groundTrainingVal, trainClasses2, 0, false, pixelsNumber); //HSV for sky sample //if (cvmGet(skyTrainingHue,0,0)!=0.0 && cvmGet(skyTrainingSat,0,0)!=0.0 && cvmGet(skyTrainingVal,0,0)!=0.0) //{ // CvKNearest knnSkyHue(skyTrainingHue, trainClasses, 0, false, pixelsNumber); //CvKNearest knnSkySat(skyTrainingSat, trainClasses, 0, false, pixelsNumber); //CvKNearest knnSkyVal(skyTrainingVal, trainClasses, 0, false, pixelsNumber); //} //scan nearest neighbors to each pixel //responseWaterH = knnWaterHue.find_nearest(sampleHue,pixelsNumber,0,0,nearestWaterH,0); //responseWaterS = knnWaterSat.find_nearest(sampleSat,pixelsNumber,0,0,nearestWaterS,0); //responseWaterV = knnWaterVal.find_nearest(sampleVal,pixelsNumber,0,0,nearestWaterV,0); //responseGroundH = knnGroundHue.find_nearest(sampleHue,pixelsNumber,0,0,nearestGroundH,0); //responseGroundS = knnGroundSat.find_nearest(sampleSat,pixelsNumber,0,0,nearestGroundS,0); //responseGroundV = knnGroundVal.find_nearest(sampleVal,pixelsNumber,0,0,nearestGroundV,0); for (int i=0;i<pixelsNumber;i++) { for (int j=0;j<pixelsNumber;j++) { if ((minH <= cvmGet(sampleHue,0,j)) || (maxH >= cvmGet(sampleHue,0,j))) //mark water samples as green comparator[0] = 1; else comparator[0] = 0; if (((minS <= cvmGet(sampleSat,0,j)) || (maxS <= cvmGet(sampleSat,0,j)))) //mark water samples as green comparator[1] = 1; else comparator[1] = 0; if ((minV <= cvmGet(sampleVal,0,j)) || (maxV <= cvmGet(sampleVal,0,j))) //mark water samples as green comparator[2] = 1; else comparator[2] = 0; //count votes for (int i3=0; i3 < 3; i3++) votesSum = votesSum + comparator[i3]; //sky detection if (votesSum > 1) //&& ((sampleSat[i][j] - sampleVal[i][j]) <= 0.1*180) { // classify pixel as water I[x-pixelsNumber+i][y-pixelsNumber+j].h = 0; I[x-pixelsNumber+i][y-pixelsNumber+j].s = 255; I[x-pixelsNumber+i][y-pixelsNumber+j].v = 255; } votesSum = 0; } } if (y < Y-1) y = y + pixelsNumber-1; if (y > Y-1) y = Y-1; else if (y == Y-1) { x = x + pixelsNumber-1; y = pixelsNumber-1; } //ix = 0; } //traverse through the image one more time, divide the image in grids of // 500x500 pixels, and see how many pixels of water are in each grid. If // most of the pixels are labeled water, then mark all the other pixels // as water as well for(int i = 0; i < 3; i++) { comparator[i] = 0; } //int counter = 0; int xDivisor = 20; int yDivisor = 20; votesSum = 0; column1 = 0; row1 = 0; x = ceil(boatFront->height/2.5); obstacleDistance = x; y = 0; int counter = 0; while (x < boatFront->height/1.2) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i < ceil(boatFront->height/xDivisor); i++) { for(int j = 0; j < ceil(boatFront->width/yDivisor); j++) { cvmSet(resampleHue,i,j,I[x+i][y+j].h); cvmSet(resampleSat,i,j,I[x+i][y+j].s); cvmSet(resampleVal,i,j,I[x+i][y+j].v); if(cvmGet(resampleHue,i,j)==0 && cvmGet(resampleSat,i,j)==255 && cvmGet(resampleVal,i,j)==255) { votesSum++; } } } if (votesSum > ((boatFront->height/xDivisor)*(boatFront->width/yDivisor)*(8.9/9))) { // if bigger than 4/5 the total number of pixels in a square, then consider the entire thing as water // We might need to use other smaller quantities (like 5/6 maybe?) for (int i = 0; i < ceil(boatFront->height/xDivisor);i++) { for (int j = 0; j < ceil(boatFront->width/yDivisor); j++) { row1 = x + i; if (row1 > X-1) row1 = X-1; column1 = y+j; I[row1][column1].h = 0; I[row1][column1].s = 255; I[row1][column1].v = 255; } } } else { // If not water, eliminate all red pixels and turn those pixels // back to the original color. These pixels shall, then, be marked // as obstacles for (int i = 0; i < ceil(boatFront->height/xDivisor);i++) { for (int j = 0; j < ceil(boatFront->width/yDivisor); j++) { row1 = x + i; if (row1 > X-1) row1 = X-1; column1 = y+j; //the darker the color, the closer the object to the boat I[row1][column1].h = 128; I[row1][column1].s = 255; I[row1][column1].v = 255 - counter; //I[row1][column1].h = IBackUp[row1][column1].h; //I[row1][column1].s = IBackUp[row1][column1].s; //I[row1][column1].v = IBackUp[row1][column1].v; //counter = counter + 20; } } //The distance formula calculated by plotting points is given by: /*********** distance = (1.76e-11)*pow(pixels,3.99) *****************/ /*********** pixel = (513.9332077469)pow(distance,0.240675506 *****************/ // Convert from pixel distance to normal distance in meters if(obstacleDistance > sqrt(pow(xObstacleDistance,2) + pow(yObstacleDistance,2))) { // x,y coordinates of the obstacle xObstacleDistance = (1.76e-11)*pow(((boatFront->height/xDivisor)+x)/2, 3.99) ; yObstacleDistance = (1.76e-11)*pow(((boatFront->width/yDivisor)+y)/2, 3.99); //xWaypoint_msg = xObstacleDistance; //yWaypoint_msg = yObstacleDistance; //publish position data //waypoint_info_pub.publish(xWaypoint_msg); //waypoint_info_pub.publish(yWaypoint_msg); //ROS_INFO("Obstacle coordinates: X = %f meters, Y = %f meters", xObstacleDistance, yObstacleDistance); obstacleDistance = sqrt(pow(xObstacleDistance,2) + pow(yObstacleDistance,2)); //ROS_INFO("Obstacle distance from: %f", obstacleDistance); } //cout << "Distance to Obstacle is: " << obstacleDistance << endl << endl; } y = y + boatFront->width/xDivisor; if (y > Y-1) { x = x + boatFront->height/yDivisor; y = 0; counter = counter + 30; } votesSum = 0; } cvCvtColor(boatFront, boatFront, CV_HSV2BGR); cvCvtColor(backUpImage, backUpImage, CV_HSV2BGR) /**************************************************************************/ try { cvShowImage("Boat Front", boatFront); } catch (sensor_msgs::CvBridgeException& e) { ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str()); } }
#include "lcd.h" #include "rtc.h" #include "mem.h" #include "sound.h" #include "save.h" /*static*/ int ver; /*static*/ int sramblock, iramblock, vramblock; /*static*/ int hramofs, hiofs, palofs, oamofs, wavofs; struct svar svars[] = { I4("GbSs", &ver), I2("PC ", &PC), I2("SP ", &SP), I2("BC ", &BC), I2("DE ", &DE), I2("HL ", &HL), I2("AF ", &AF), I4("IME ", &cpu.ime), I4("ima ", &cpu.ima), I4("spd ", &cpu.speed), I4("halt", &cpu.halt), I4("div ", &cpu.div), I4("tim ", &cpu.tim), I4("lcdc", &cpu.lcdc),
/* decode binex mesaage 0x01-06: decoded qzss ephmemeris ---------------------*/ static int decode_bnx_01_06(raw_t *raw, unsigned char *buff, int len) { eph_t eph={0}; unsigned char *p=buff; double tow,ura,sqrtA; int prn,flag; trace(4,"binex 0x01-06: len=%d\n",len); if (len>=127) { prn =U1(p); p+=1; eph.week =U2(p); p+=2; tow =I4(p); p+=4; eph.toes =I4(p); p+=4; eph.tgd[0]=R4(p); p+=4; eph.iodc =I4(p); p+=4; eph.f2 =R4(p); p+=4; eph.f1 =R4(p); p+=4; eph.f0 =R4(p); p+=4; eph.iode =I4(p); p+=4; eph.deln =R4(p)*SC2RAD; p+=4; eph.M0 =R8(p); p+=8; eph.e =R8(p); p+=8; sqrtA =R8(p); p+=8; eph.cic =R4(p); p+=4; eph.crc =R4(p); p+=4; eph.cis =R4(p); p+=4; eph.crs =R4(p); p+=4; eph.cuc =R4(p); p+=4; eph.cus =R4(p); p+=4; eph.OMG0 =R8(p); p+=8; eph.omg =R8(p); p+=8; eph.i0 =R8(p); p+=8; eph.OMGd =R4(p)*SC2RAD; p+=4; eph.idot =R4(p)*SC2RAD; p+=4; ura =R4(p)*0.1; p+=4; eph.svh =U2(p); p+=2; flag =U2(p); } else { trace(2,"binex 0x01-06: length error len=%d\n",len); return -1; } if (!(eph.sat=satno(SYS_QZS,prn))) { trace(2,"binex 0x01-06: satellite error prn=%d\n",prn); return 0; } eph.A=sqrtA*sqrtA; eph.toe=gpst2time(eph.week,eph.toes); eph.toc=gpst2time(eph.week,eph.toes); eph.ttr=adjweek(eph.toe,tow); eph.fit=(flag&0x01)?0.0:2.0; /* 0:2hr,1:>2hr */ eph.sva=uraindex(ura); eph.code=2; /* codes on L2 channel */ if (!strstr(raw->opt,"-EPHALL")) { if (raw->nav.eph[eph.sat-1].iode==eph.iode&& raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ } raw->nav.eph[eph.sat-1]=eph; raw->ephsat=eph.sat; return 2; }
/* decode binex mesaage 0x01-05: decoded beidou-2/compass ephmemeris ---------*/ static int decode_bnx_01_05(raw_t *raw, unsigned char *buff, int len) { eph_t eph={0}; unsigned char *p=buff; double tow,toc,sqrtA; int prn,flag1,flag2; trace(4,"binex 0x01-05: len=%d\n",len); if (len>=117) { prn =U1(p); p+=1; eph.week =U2(p); p+=2; tow =I4(p); p+=4; toc =I4(p); p+=4; eph.toes =I4(p); p+=4; eph.f2 =R4(p); p+=4; eph.f1 =R4(p); p+=4; eph.f0 =R4(p); p+=4; eph.deln =R4(p)*SC2RAD; p+=4; eph.M0 =R8(p); p+=8; eph.e =R8(p); p+=8; sqrtA =R8(p); p+=8; eph.cic =R4(p); p+=4; eph.crc =R4(p); p+=4; eph.cis =R4(p); p+=4; eph.crs =R4(p); p+=4; eph.cuc =R4(p); p+=4; eph.cus =R4(p); p+=4; eph.OMG0 =R8(p); p+=8; eph.omg =R8(p); p+=8; eph.i0 =R8(p); p+=8; eph.OMGd =R4(p)*SC2RAD; p+=4; eph.idot =R4(p)*SC2RAD; p+=4; flag1 =U2(p); p+=2; flag2 =U4(p); } else { trace(2,"binex 0x01-05: length error len=%d\n",len); return -1; } if (!(eph.sat=satno(SYS_CMP,prn))) { trace(2,"binex 0x01-05: satellite error prn=%d\n",prn); return 0; } eph.A=sqrtA*sqrtA; eph.toe=gpst2time(eph.week+1356,eph.toes+14.0); /* bdt -> gpst */ eph.toc=gpst2time(eph.week+1356,eph.toes+14.0); /* bdt -> gpst */ eph.ttr=adjweek(eph.toe,tow+14.0); /* bdt -> gpst */ eph.iodc=(flag1>>1)&0x1F; eph.iode=(flag1>>6)&0x1F; eph.svh=flag1&0x01; eph.sva=flag2&0x0F; /* ura index */ eph.tgd[0]=bds_tgd(flag2>> 4); /* TGD1 (s) */ eph.tgd[1]=bds_tgd(flag2>>14); /* TGD2 (s) */ eph.flag=(flag1>>11)&0x07; /* nav type (0:unknown,1:IGSO/MEO,2:GEO) */ eph.code=(flag2>>25)&0x7F; /* message source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q)*/ if (!strstr(raw->opt,"-EPHALL")) { if (raw->nav.eph[eph.sat-1].iode==eph.iode&& raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ } raw->nav.eph[eph.sat-1]=eph; raw->ephsat=eph.sat; return 2; }
/* decode binex mesaage 0x01-04: decoded galileo ephmemeris ------------------*/ static int decode_bnx_01_04(raw_t *raw, unsigned char *buff, int len) { eph_t eph={0}; unsigned char *p=buff; double tow,ura,sqrtA; int prn; trace(4,"binex 0x01-04: len=%d\n",len); if (len>=127) { prn =U1(p)+1; p+=1; eph.week =U2(p); p+=2; tow =I4(p); p+=4; eph.toes =I4(p); p+=4; eph.tgd[0]=R4(p); p+=4; /* BGD E5a/E1 */ eph.tgd[1]=R4(p); p+=4; /* BGD E5b/E1 */ eph.iode =I4(p); p+=4; /* IODnav */ eph.f2 =R4(p); p+=4; eph.f1 =R4(p); p+=4; eph.f0 =R4(p); p+=4; eph.deln =R4(p)*SC2RAD; p+=4; eph.M0 =R8(p); p+=8; eph.e =R8(p); p+=8; sqrtA =R8(p); p+=8; eph.cic =R4(p); p+=4; eph.crc =R4(p); p+=4; eph.cis =R4(p); p+=4; eph.crs =R4(p); p+=4; eph.cuc =R4(p); p+=4; eph.cus =R4(p); p+=4; eph.OMG0 =R8(p); p+=8; eph.omg =R8(p); p+=8; eph.i0 =R8(p); p+=8; eph.OMGd =R4(p)*SC2RAD; p+=4; eph.idot =R4(p)*SC2RAD; p+=4; ura =R4(p)*0.1; p+=4; eph.svh =U2(p); p+=2; eph.code =U2(p); /* data source */ } else { trace(2,"binex 0x01-04: length error len=%d\n",len); return -1; } if (!(eph.sat=satno(SYS_GAL,prn))) { trace(2,"binex 0x01-04: satellite error prn=%d\n",prn); return -1; } eph.A=sqrtA*sqrtA; eph.iode=eph.iodc; eph.toe=gpst2time(eph.week,eph.toes); eph.toc=gpst2time(eph.week,eph.toes); eph.ttr=adjweek(eph.toe,tow); eph.sva=uraindex(ura); if (!strstr(raw->opt,"-EPHALL")) { if (raw->nav.eph[eph.sat-1].iode==eph.iode&& raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ } raw->nav.eph[eph.sat-1]=eph; raw->ephsat=eph.sat; return 2; }
void Filter::Kalman(Joint joint, double &dx, double &dy) { Kalmans[Kalman_count++] = joint; Kalman_count = Kalman_count % Kalman_limit; Kalman_num++; if (Kalman_num > Kalman_limit) { Kalman_num = Kalman_limit; } if (Kalman_num < Kalman_limit) { dx = joint.Position.X; dy = joint.Position.Y; return; } else { //X, Y int haha; haha = 1; double x[5], y[5]; int pos = Kalman_count; for (int i = 0; i < 5; i++) { x[i] = Kalmans[pos].Position.X; y[i] = Kalmans[pos].Position.Y; pos++; pos = pos%Kalman_limit; } //求系数Ax, Ay double Ax[5] = { /*a0*/ x[0], /*a1*/ 4 * (x[1] - x[0]) - 3 * x[2] + 4 * x[3] / 3 - x[4] / 4, /*a2*/ 11 * x[4] / 24 - 7 * x[3] / 3 + 19 * x[2] / 4 - 13 * (x[1] - x[0]) / 3, /*a3*/ x[4] / 3 - 7 * x[3] / 6 + x[2] - (x[1] - x[0]) / 2, /*a4*/ (x[4] - 4 * x[3] + 6 * x[2] + 4 * (x[1] - x[0])) / 24 }; double Ay[5] = { /*a0*/ y[0], /*a1*/ 4 * (y[1] - y[0]) - 3 * y[2] + 4 * y[3] / 3 - y[4] / 4, /*a2*/ 11 * y[4] / 24 - 7 * y[3] / 3 + 19 * y[2] / 4 - 13 * (y[1] - y[0]) / 3, /*a3*/ y[4] / 3 - 7 * y[3] / 6 + y[2] - (y[1] - y[0]) / 2, /*a4*/ (y[4] - 4 * y[3] + 6 * y[2] + 4 * (y[1] - y[0])) / 24 }; //求转换矩阵Fx, Fy Matrix Fx(4, 4, new double[16]{ 1, 1, -0.5, (Ax[1] + 6 * Ax[3] - 4 * Ax[4]) / (24 * Ax[4]), 0, 1, 1, 0.5, 0, 0, 1, 1, 0, 0, 0, 1}); Matrix Fy(4, 4, new double[16]{ 1, 1, -0.5, (Ay[1] + 6 * Ay[3] - 4 * Ay[4]) / (24 * Ay[4]), 0, 1, 1, 0.5, 0, 0, 1, 1, 0, 0, 0, 1}); //求ε(t|t-1) Matrix ex(4, 4), ey(4, 4); ex = Fx*Kalman_ex*(!Fx); ey = Fy*Kalman_ey*(!Fy); //cout << "ex" << endl; ex.print(); //cout << "ey" << endl; ey.print(); Matrix Bx(4, 1), By(4, 1); //cout << "!Kalman_C" << endl; (!Kalman_C).print(); //cout << "Kalman_vx" << endl; Kalman_vx.print(); //cout << "Kalman_C" << endl; Kalman_C.print(); //cout << "!Kalman_C" << endl; (!Kalman_C).print(); //cout << "Kalman_C*ex" << endl; (Kalman_C*ex).print(); //cout << "Kalman_C*ex*(!Kalman_C)" << endl; (Kalman_C*ex*(!Kalman_C)).print(); //cout << "(~(Kalman_vx + Kalman_C*ex*(!Kalman_C)))" << endl; //(~(Kalman_vx + Kalman_C*ex*(!Kalman_C))).print(); Bx = ex*(!Kalman_C)*(~(Kalman_vx + Kalman_C*ex*(!Kalman_C))); //cout << "Bx" << endl; Bx.print(); By = ey*(!Kalman_C)*(~(Kalman_vy + Kalman_C*ey*(!Kalman_C))); Matrix I4(4, 4); I4.SetIdentity(); Kalman_Sx = (I4 - Bx*Kalman_C)*(Fx*Kalman_Sx + Kalman_Gx) + Bx*Matrix(1, 1, new double[1] {joint.Position.X}); //cout << "Kalman_Sx" << endl; Kalman_Sx.print(); Kalman_Sy = (I4 - By*Kalman_C)*(Fy*Kalman_Sy + Kalman_Gy) + By*Matrix(1, 1, new double[1] {joint.Position.Y}); Kalman_ex = ex - Bx*Kalman_C*ex; Kalman_ey = ey - By*Kalman_C*ey; dx = Kalman_Sx.at(0, 0); dy = Kalman_Sy.at(0, 0); } }
/* decode ubx-nav-pvt: navigation pvt -----------------------------------*/ int decode_navpvt(tUbxRawData *raw) { UbxMsg01_07_PVT pvt; unsigned char *p = raw->buff + UBX_MSGSTART_SHIFT; memset(&pvt, 0, sizeof(pvt)); pvt.iTOW = U4(p); pvt.year = U2(p+4); pvt.month = U1(p+6); pvt.day = U1(p+7); pvt.hour = U1(p+8); pvt.min = U1(p+9); pvt.sec = U1(p+10); pvt.bitfield = U1(p+11); pvt.timeUnc = U4(p+12); pvt.nano = I4(p+16); pvt.fixType = U1(p+20); pvt.flags = U1(p+21); pvt.flags2 = U1(p+22); pvt.numSV = U1(p+23); pvt.Lon = I4(p+24); pvt.Lat = I4(p+28); pvt.Alt = I4(p+32); pvt.AltMsl = I4(p+36); pvt.hErr = U4(p+40); pvt.vErr = U4(p+44); pvt.Vn = I4(p+48); pvt.Ve = I4(p+52); pvt.Vd = I4(p+56); pvt.groundSpeed = I4(p+60); pvt.heading = I4(p+64); pvt.spdErr = U4(p+68); pvt.headingErr = U4(p+72); pvt.PDOP = U2(p+76); memcpy(pvt.reserved1, p+78, 6*sizeof(unsigned char)); pvt.headVel = I4(p+84); memcpy(pvt.reserved2, p+88, 4*sizeof(unsigned char)); /* fill up interface for real time processing */ pb_Set_ExternalUbxGNSS_PVT(&pvt); /*----- validate PPS -----*/ pb_Validate_Ubx_PPS(&pvt); return 0; }
/* generate ublox binary message ----------------------------------------------- * generate ublox binary message from message string * args : char *msg IO message string * "CFG-PRT portid res0 res1 mode baudrate inmask outmask flags" * "CFG-USB vendid prodid res1 res2 power flags vstr pstr serino" * "CFG-MSG msgid rate0 rate1 rate2 rate3" * "CFG-NMEA filter version numsv flags" * "CFG-RATE meas nav time" * "CFG-CFG clear_mask save_mask load_mask" * "CFG-TP interval length status time_ref res adelay rdelay udelay" * "CFG-NAV2 ..." * "CFG-DAT maja flat dx dy dz rotx roty rotz scale" * "CFG-INF protocolid res0 res1 mask0 mask1 mask2 mask3" * "CFG-RST navbbr reset res" * "CFG-RXM gpsmode lpmode" * "CFG-ANT flags pins" * "CFG-FXN flags treacq tacq treacqoff tacqoff ton toff res basetow" * "CFG-SBAS mode usage maxsbas res scanmode" * "CFG-LIC key0 key1 key2 key3 key4 key5" * "CFG-TM intid rate flags" * "CFG-TM2 ch res0 res1 rate flags" * "CFG-TMODE tmode posx posy posz posvar svinmindur svinvarlimit" * "CFG-EKF ..." * unsigned char *buff O binary message * return : length of binary message (0: error) * note : see reference [1] for details. *-----------------------------------------------------------------------------*/ extern int gen_ubx(const char *msg, unsigned char *buff) { const char *cmd[]={ "PRT","USB","MSG","NMEA","RATE","CFG","TP","NAV2","DAT","INF", "RST","RXM","ANT","FXN","SBAS","LIC","TM","TM2","TMODE","EKF","" }; const unsigned char id[]={ 0x00,0x1B,0x01,0x17,0x08,0x09,0x07,0x1A,0x06,0x02, 0x04,0x11,0x13,0x0E,0x16,0x80,0x10,0x19,0x1D,0x12 }; const int prm[][32]={ {FU1,FU1,FU2,FU4,FU4,FU2,FU2,FU2,FU2}, /* PRT */ {FU2,FU2,FU2,FU2,FU2,FU2,FS32,FS32,FS32}, /* USB */ {FU1,FU1,FU1,FU1,FU1,FU1}, /* MSG */ {FU1,FU1,FU1,FU1}, /* NMEA */ {FU2,FU2,FU2}, /* RATE */ {FU4,FU4,FU4}, /* CFG */ {FU4,FU4,FI1,FU1,FU2,FI2,FI2,FI4}, /* TP */ {FU1,FU1,FU2,FU1,FU1,FU1,FU1,FI4,FU1,FU1,FU1,FU1,FU1,FU1,FU2,FU2,FU2,FU2, FU2,FU1,FU1,FU2,FU4,FU4}, /* NAV2 */ {FR8,FR8,FR4,FR4,FR4,FR4,FR4,FR4,FR4}, /* DAT */ {FU1,FU1,FU2,FU1,FU1,FU1,FU1}, /* INF */ {FU2,FU1,FU1}, /* RST */ {FU1,FU1}, /* RXM */ {FU2,FU2}, /* ANT */ {FU4,FU4,FU4,FU4,FU4,FU4,FU4,FU4}, /* FXN */ {FU1,FU1,FU1,FU1,FU4}, /* SBAS */ {FU2,FU2,FU2,FU2,FU2,FU2}, /* LIC */ {FU4,FU4,FU4}, /* TM */ {FU1,FU1,FU2,FU4,FU4}, /* TM2 */ {FU4,FI4,FI4,FI4,FU4,FU4,FU4}, /* TMODE */ {FU1,FU1,FU1,FU1,FU4,FU2,FU2,FU1,FU1,FU2} /* EKF */ }; unsigned char *q=buff; char mbuff[1024],*args[32],*p; int i,j,n,narg=0; trace(4,"gen_ubxf: msg=%s\n",msg); strcpy(mbuff,msg); for (p=strtok(mbuff," ");p&&narg<32;p=strtok(NULL," ")) { args[narg++]=p; } if (narg<1||strncmp(args[0],"CFG-",4)) return 0; for (i=0;*cmd[i];i++) { if (!strcmp(args[0]+4,cmd[i])) break; } if (!*cmd[i]) return 0; *q++=UBXSYNC1; *q++=UBXSYNC2; *q++=UBXCFG; *q++=id[i]; q+=2; for (j=1;prm[i][j-1]>0;j++) { switch (prm[i][j-1]) { case FU1 : U1(q)=j<narg?(unsigned char )atoi(args[j]):0; q+=1; break; case FU2 : U2(q)=j<narg?(unsigned short)atoi(args[j]):0; q+=2; break; case FU4 : U4(q)=j<narg?(unsigned int )atoi(args[j]):0; q+=4; break; case FI1 : I1(q)=j<narg?(char )atoi(args[j]):0; q+=1; break; case FI2 : I2(q)=j<narg?(short )atoi(args[j]):0; q+=2; break; case FI4 : I4(q)=j<narg?(int )atoi(args[j]):0; q+=4; break; case FR4 : R4(q)=j<narg?(float )atof(args[j]):0; q+=4; break; case FR8 : setR8(q,j<narg?(double)atof(args[j]):0); q+=8; break; case FS32: sprintf((char *)q,"%-32.32s",j<narg?args[j]:""); q+=32; break; } } n=(int)(q-buff)+2; U2(buff+4)=(unsigned short)(n-8); setcs(buff,n); trace(5,"gen_ubxf: buff=\n"); traceb(5,buff,n); return n; }
void imageCallback(const sensor_msgs::ImageConstPtr& msg) { //bridge that will transform the message (image) from ROS code back to "image" code sensor_msgs::CvBridge bridge; fprintf(stderr, "\n call Back funtion \n"); //publish data (obstacle waypoints) back to the boat //ros::NodeHandle n; //std_msgs::Float32 xWaypoint_msg; // X coordinate obstacle message //std_msgs::Float32 yWaypoint_msg; // Y coordinate obstacle message //publish the waypoint data //ros::Publisher waypoint_info_pub = n.advertise<std_msgs::Float32>("waypoint_info", 1000); //ros::Publisher Ywaypoint_info_pub = n.advertise<std_msgs::Float32>("waypoint_info", 1000); //std::stringstream ss; /***********************************************************************/ //live image coming streamed straight from the boat's camera IplImage* boatFront = bridge.imgMsgToCv(msg, "bgr8"); //The boat takes flipped images, so you need to flip them back to normal cvFlip(boatFront, boatFront, 0); IplImage* backUpImage = cvCloneImage(boatFront); boatFront->origin = IPL_ORIGIN_TL; //sets image origin to top left corner int X = boatFront->height; int Y = boatFront->width; //cout << "height " << X << endl; //cout << "width " << Y << endl; /*********************Image Filtering variables****************************/ //these images are used for segmenting objects from the overall background //create a one channel image to convert from RGB to GRAY IplImage* grayImage = cvCreateImage(cvGetSize(boatFront),IPL_DEPTH_8U,1); //convert grayImage to binary (final step after converting from GRAY) IplImage* bwImage = cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_8U,1); //variables used for the flood fill segmentation CvPoint seed_point = cvPoint(boatFront->height/1.45,0); //not sure how this variable works CvScalar color = CV_RGB(250,0,0); CvMemStorage* grayStorage = NULL; //memory storage for contour sequence CvSeq* contours = 0; // get blobs and filter them using their area //IplConvKernel* morphKernel = cvCreateStructuringElementEx(5, 5, 1, 1, CV_SHAPE_RECT, NULL); //IplImage* original, *originalThr; //IplImage* segmentated = cvCreateImage(cvGetSize(boatFront), 8, 1); //unsigned int blobNumber = 0; //IplImage* labelImg = cvCreateImage(cvGetSize(boatFront), IPL_DEPTH_LABEL, 1); CvMoments moment; /***********************************************************************/ //boat's edge distance from the camera. This is used for visual calibration //to know the distance from the boat to the nearest obstacles. //With respect to the mounted camera, distance is 21 inches (0.5334 m) side to side //and 15 inches (0.381 m). //float boatFrontDistance = 0.381; //distance in meters //float boatSideDistance = 0.5334; //distance in meters // These variables tell the distance from the center bottom of the image // (the camera) to the square surrounding a the obstacle float xObstacleDistance = 0.0; float yObstacleDistance = 0.0; float obstacleDistance = 0.0; float obstacleHeading = 0.0; int pixelsNumber = 50; //number of pixels for an n x n matrix and # of neighbors const int arraySize = pixelsNumber; const int threeArraySize = pixelsNumber; //if n gets changed, then the algorithm might have to be //recalibrated. Try to keep it constant //these variables are used for the k nearest neighbors //int accuracy; //reponses for each of the classifications float responseWaterH, responseWaterS, responseWaterV; float responseGroundH, responseGroundS, responseGroundV; float responseSkyH, responseSkyS, responseSkyV; float averageHue = 0.0; float averageSat = 0.0; float averageVal = 0.0; CvMat* trainClasses = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); CvMat* trainClasses2 = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); //CvMat sample = cvMat( 1, 2, CV_32FC1, _sample ); //used with the classifier CvMat* trainClassesH = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); CvMat* trainClassesS = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); CvMat* trainClassesV = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); //CvMat* trainClasses2 = cvCreateMat( pixelsNumber, 1, CV_32FC1 ); //CvMat sample = cvMat( 1, 2, CV_32FC1, _sample ); //used with the classifier /*CvMat* nearestWaterH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestWaterS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestWaterV = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestGroundH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestGroundS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestGroundV = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestSkyH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestSkyS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* nearestSkyV = cvCreateMat(1, pixelsNumber, CV_32FC1); //Distance CvMat* distanceWaterH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceWaterS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceWaterV = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceGroundH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceGroundS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceGroundV = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceSkyH = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceSkyS = cvCreateMat(1, pixelsNumber, CV_32FC1); CvMat* distanceSkyV = cvCreateMat(1, pixelsNumber, CV_32FC1); */ //these variables are use to traverse the picture by blocks of n x n pixels at //a time. //Index(0,0) does not exist, so make sure kj and ki start from 1 (in the //right way, of course) //x and y are the dimensions of the local patch of pixels int x = (boatFront->height)/1.45;//(boatFront->height)/2.5 + 105; int y = 0; int skyX = 0; int skyY = 0; int row1 = 0; int column1 = 0; //these two variables are used in order to divide the grid in the //resample segmentation part int xDivisor = 200; int yDivisor = 200; //ground sample //CvMat* groundTrainingHue = cvCreateMat(threeArraySize,arraySize,CV_32FC1); //CvMat* groundTrainingSat = cvCreateMat(threeArraySize,arraySize,CV_32FC1); //CvMat* groundTrainingVal = cvCreateMat(threeArraySize,arraySize,CV_32FC1); //water sample CvMat* waterTrainingHue = cvCreateMat(threeArraySize,arraySize,CV_32FC1); CvMat* waterTrainingSat = cvCreateMat(threeArraySize,arraySize,CV_32FC1); CvMat* waterTrainingVal = cvCreateMat(threeArraySize,arraySize,CV_32FC1); //n x n sample patch taken from the picture CvMat* sampleHue = cvCreateMat(1,arraySize,CV_32FC1); CvMat* sampleSat = cvCreateMat(1,arraySize,CV_32FC1); CvMat* sampleVal = cvCreateMat(1,arraySize,CV_32FC1); CvMat* resampleHue = cvCreateMat(boatFront->height/xDivisor,boatFront->width/yDivisor,CV_32FC1); CvMat* resampleSat = cvCreateMat(boatFront->height/xDivisor,boatFront->width/yDivisor,CV_32FC1); CvMat* resampleVal = cvCreateMat(boatFront->height/xDivisor,boatFront->width/yDivisor,CV_32FC1); int xDiv = 20; int yDiv = 20; CvMat* resampleHue2 = cvCreateMat(boatFront->height/xDiv,boatFront->width/yDiv,CV_32FC1); CvMat* resampleSat2 = cvCreateMat(boatFront->height/xDiv,boatFront->width/yDiv,CV_32FC1); CvMat* resampleVal2 = cvCreateMat(boatFront->height/xDiv,boatFront->width/yDiv,CV_32FC1); //sky training sample CvMat* skyTrainingHue = cvCreateMat(arraySize,arraySize,CV_32FC1); CvMat* skyTrainingSat = cvCreateMat(arraySize,arraySize,CV_32FC1); CvMat* skyTrainingVal = cvCreateMat(arraySize,arraySize,CV_32FC1); //initialize each matrix element to zero for ease of use //cvZero(groundTrainingHue); //cvZero(groundTrainingSat); //cvZero(groundTrainingVal); cvZero(waterTrainingHue); cvZero(waterTrainingSat); cvZero(waterTrainingVal); cvZero(sampleHue); cvZero(sampleSat); cvZero(sampleVal); cvZero(resampleHue); cvZero(resampleSat); cvZero(resampleVal); cvZero(skyTrainingHue); cvZero(skyTrainingSat); cvZero(skyTrainingVal); //Stores the votes for each channel (whether it belongs to water or not //1 is part of water, 0 not part of water //if sum of votes is bigger than 1/2 the number of elements, then it belongs to water int votesSum = 0; int comparator[3]; //used when only three votes are needed //int comparatorTwo [3][3]; //used when six votes are needed //initial sum of votes is zero //Error if initialize both matrices inside a single for loop. Dont know why for(int i = 0; i < 3; i++) { comparator[i] = 0; } /***********************************************************************/ //Convert from RGB to HSV to control the brightness of the objects. //work with reflexion /*Sky recognition. Might be useful for detecting reflexion on the water. If the sky is detected, and the reflection has the same characteristics of something below the horizon, that "something" might be water. Assume sky wont go below the horizon */ //convert from RGB to HSV cvCvtColor(boatFront, boatFront, CV_BGR2HSV); cvCvtColor(backUpImage, backUpImage, CV_BGR2HSV); HsvImage I(boatFront); HsvImage IBackUp(backUpImage); //Sky detection /* for (int i=0; i<boatFront->height;i++) { for (int j=0; j<boatFront->width;j++) { //if something is bright enough, consider it sky and store the //value. HSV values go from 0 to 180 ... RGB goes from 0 to 255 if (((I[i][j].v >= 180) && (I[i][j].s <= 16))) // && ((I[i][j].h >=10)))) //&& (I[i][j].h <= 144)))) { //The HSV values vary between 0 and 1 cvmSet(skyTrainingHue,skyX,skyY,I[i][j].h); cvmSet(skyTrainingSat,skyX,skyY,I[i][j].s); cvmSet(skyTrainingVal,skyX,skyY,I[i][j].v); //I[i][j].h = 0.3*180; //H (color) //I[i][j].s = 0.3*180; //S (color intensity) //I[i][j].v = 0.6*180; //V (brightness) if (skyY == pixelsNumber-1) { if (skyX == pixelsNumber-1) skyX = 1; else skyX = skyX + 1; skyY = 1; } else skyY = skyY + 1; } } } /***********************************************************************/ //offline input pictures. Samples of water properties are taken from these //pictures to get a range of values for H, S, V that will be stored into a //pre-defined classifier IplImage* imageSample1 = cvLoadImage("20110805_032255.jpg"); cvSetImageROI(imageSample1, cvRect(0,0,imageSample1->height/0.5,imageSample1->width/1.83)); cvCvtColor(imageSample1, imageSample1, CV_BGR2HSV); HsvImage I1(imageSample1); IplImage* imageSample2 = cvLoadImage("20110805_032257.jpg"); cvCvtColor(imageSample2, imageSample2, CV_BGR2HSV); HsvImage I2(imageSample2); IplImage* imageSample3 = cvLoadImage("20110805_032259.jpg"); cvCvtColor(imageSample3, imageSample3, CV_BGR2HSV); HsvImage I3(imageSample3); IplImage* imageSample4 = cvLoadImage("20110805_032301.jpg"); cvCvtColor(imageSample4, imageSample4, CV_BGR2HSV); HsvImage I4(imageSample4); IplImage* imageSample5 = cvLoadImage("20110805_032303.jpg"); cvCvtColor(imageSample5, imageSample5, CV_BGR2HSV); HsvImage I5(imageSample5); IplImage* imageSample6 = cvLoadImage("20110805_032953.jpg"); cvCvtColor(imageSample6, imageSample6, CV_BGR2HSV); HsvImage I6(imageSample6); IplImage* imageSample7 = cvLoadImage("20110805_032955.jpg"); cvCvtColor(imageSample7, imageSample7, CV_BGR2HSV); HsvImage I7(imageSample7); IplImage* imageSample8 = cvLoadImage("20110805_032957.jpg"); cvCvtColor(imageSample8, imageSample8, CV_BGR2HSV); HsvImage I8(imageSample8); IplImage* imageSample9 = cvLoadImage("20110805_032959.jpg"); cvCvtColor(imageSample9, imageSample9, CV_BGR2HSV); HsvImage I9(imageSample9); IplImage* imageSample10 = cvLoadImage("20110805_033001.jpg"); cvCvtColor(imageSample10, imageSample10, CV_BGR2HSV); HsvImage I10(imageSample10); IplImage* imageSample11 = cvLoadImage("20110805_033009.jpg"); cvCvtColor(imageSample11, imageSample11, CV_BGR2HSV); HsvImage I11(imageSample11); IplImage* imageSample12 = cvLoadImage("20110805_033011.jpg"); cvCvtColor(imageSample12, imageSample12, CV_BGR2HSV); HsvImage I12(imageSample12); for (int i=0; i < threeArraySize; i++) { for (int j=0; j < arraySize; j++) { row1 = ceil(X/1.2866)+ceil(X/5.237)+i+ceil(-X/3.534545455) + ceil(X/4.8); column1 = ceil(Y/7.0755)+ceil(Y/21.01622)+j+ceil(X/1.495384615); averageHue = (I1[row1][column1].h + I2[row1][column1].h + I3[row1][column1].h + I4[row1][column1].h + I5[row1][column1].h + I6[row1][column1].h + I7[row1][column1].h + I8[row1][column1].h + I9[row1][column1].h + I10[row1][column1].h + I11[row1][column1].h + I12[row1][column1].h) / 12; averageSat = (I1[row1][column1].s + I2[row1][column1].s + I3[row1][column1].s + I4[row1][column1].s + I5[row1][column1].s + I6[row1][column1].s + I7[row1][column1].s + I8[row1][column1].s + I9[row1][column1].s + I10[row1][column1].s + I11[row1][column1].s + I12[row1][column1].s) / 12; averageVal = (I1[row1][column1].v + I2[row1][column1].v + I3[row1][column1].v + I4[row1][column1].v + I5[row1][column1].v + I6[row1][column1].v + I7[row1][column1].v + I8[row1][column1].v + I9[row1][column1].v + I10[row1][column1].v + I11[row1][column1].v + I12[row1][column1].v) / 12; //water patch sample (n X n matrix) cvmSet(waterTrainingHue,i,j,averageHue); cvmSet(waterTrainingSat,i,j,averageSat); cvmSet(waterTrainingVal,i,j,averageVal); //patch is red (this is for me to know where the ground patch sample is) //I[row1][column1].h = 0; //I[row1][column1].s = 255; //I[row1][column1].v = 255; } } //creating a training sample from the an image taken on the fly row1 = 0; column1 = 0; for (int i=0; i<pixelsNumber; i++) { for (int j=0; j<pixelsNumber; j++) { row1 = ceil(X/1.2866)+ceil(X/5.237)+i+ceil(-X/3.534545455) + ceil(X/4.8); column1 = ceil(Y/7.0755)+ceil(Y/21.01622)+j+ceil(X/1.495384615); cvmSet(trainClassesH,i,0,I[row1][column1].h); cvmSet(trainClassesS,i,0,I[row1][column1].s); cvmSet(trainClassesV,i,0,I[row1][column1].v); } } //order the water samples in ascending order on order to know a range cvSort(waterTrainingHue, waterTrainingHue, CV_SORT_ASCENDING); cvSort(waterTrainingSat, waterTrainingSat, CV_SORT_ASCENDING); cvSort(waterTrainingVal, waterTrainingVal, CV_SORT_ASCENDING); // find the maximum and minimum values in the array to create a range int maxH = cvmGet(waterTrainingHue,0,0); int maxS = cvmGet(waterTrainingSat,0,0); int maxV = cvmGet(waterTrainingVal,0,0); int minH = cvmGet(waterTrainingHue,0,0); int minS = cvmGet(waterTrainingSat,0,0); int minV = cvmGet(waterTrainingVal,0,0); for (int i=0; i < threeArraySize; i++) { for (int j=0; j < arraySize; j++) { if (cvmGet(waterTrainingHue,i,j) > maxH) maxH = cvmGet(waterTrainingHue,i,j); if (cvmGet(waterTrainingSat,i,j) > maxS) maxS = cvmGet(waterTrainingHue,i,j); if (cvmGet(waterTrainingVal,i,j) > maxV) maxV = cvmGet(waterTrainingVal,i,j); if (cvmGet(waterTrainingHue,i,j) < minH) minH = cvmGet(waterTrainingHue,i,j); if (cvmGet(waterTrainingSat,i,j) < minS) minS = cvmGet(waterTrainingSat,i,j); if (cvmGet(waterTrainingVal,i,j) < minV) minV = cvmGet(waterTrainingVal,i,j); } } //cout << "Min Value in the range: " << endl; //cout << minH << endl; //cout << minS << endl; //cout << minV << endl; //cout << "Max Value in the range: " << endl; //cout << maxH << endl; //cout << maxS << endl; //cout << maxV << endl << endl; /*********** Main loop. It traverses through the picture**********/ /**********************************************************************/ //Ignore unused parts of the image and convert them to black // for (int i=0; i<boatFront->height/1.45 - 1;i++) //{ // for (int j=0; j<Y-1;j++) // { // I[i][j].h = 0; // I[i][j].s = 0; // I[i][j].v = 0; // } // } /********************************************************************* // Use nearest neighbors to increase accuracy skyX = 0; skyY = 0; while (x < X-1) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i<6;i++) { column1 = y+i; if (column1 > Y-1) column1 = Y-1; cvmSet(sampleHue,0,i,I[x][column1].h); cvmSet(sampleSat,0,i,I[x][column1].s); cvmSet(sampleVal,0,i,I[x][column1].v); } //Find the shortest distance between a pixel and the neighbors from each of //the training samples (sort of inefficient, but might do the job...sometimes) //HSV for water sample // learn classifier //CvKNearest knn(trainData, trainClasses, 0, false, itemsNumber); CvKNearest knnWaterHue(waterTrainingHue, trainClassesH, 0, false, pixelsNumber); CvKNearest knnWaterSat(waterTrainingSat, trainClassesS, 0, false, pixelsNumber); CvKNearest knnWaterVal(waterTrainingVal, trainClassesV, 0, false, pixelsNumber); //HSV for ground sample //CvKNearest knnGroundHue(groundTrainingHue, trainClasses2, 0, false, pixelsNumber); //CvKNearest knnGroundSat(groundTrainingSat, trainClasses2, 0, false, pixelsNumber); //CvKNearest knnGroundVal(groundTrainingVal, trainClasses2, 0, false, pixelsNumber); //HSV for sky sample //if (cvmGet(skyTrainingHue,0,0)!=0.0 && cvmGet(skyTrainingSat,0,0)!=0.0 && cvmGet(skyTrainingVal,0,0)!=0.0) //{ // CvKNearest knnSkyHue(skyTrainingHue, trainClasses, 0, false, pixelsNumber); // CvKNearest knnSkySat(skyTrainingSat, trainClasses, 0, false, pixelsNumber); // CvKNearest knnSkyVal(skyTrainingVal, trainClasses, 0, false, pixelsNumber); //} //scan nearest neighbors to each pixel responseWaterH = knnWaterHue.find_nearest(sampleHue,pixelsNumber,0,0,nearestWaterH,0); responseWaterS = knnWaterSat.find_nearest(sampleSat,pixelsNumber,0,0,nearestWaterS,0); responseWaterV = knnWaterVal.find_nearest(sampleVal,pixelsNumber,0,0,nearestWaterV,0); //responseGroundH = knnGroundHue.find_nearest(sampleHue,pixelsNumber,0,0,nearestGroundH,0); //responseGroundS = knnGroundSat.find_nearest(sampleSat,pixelsNumber,0,0,nearestGroundS,0); //responseGroundV = knnGroundVal.find_nearest(sampleVal,pixelsNumber,0,0,nearestGroundV,0); //for (int i=0;i<pixelsNumber;i++) //{ for (int j=0;j<pixelsNumber;j++) { if ((nearestWaterH->data.fl[j] == responseWaterH) )//&& (nearestWaterH->data.fl[j] == responseWaterH + 5)) // mark water samples as green comparator[0] = 1; else comparator[0] = 0; if ((nearestWaterS->data.fl[j] == responseWaterS) )//&& (nearestWaterS->data.fl[j] < responseWaterS + 5)) //mark water samples as green comparator[1] = 1; else comparator[1] = 0; if ((nearestWaterV->data.fl[j] == responseWaterV) )//&& (nearestWaterV->data.fl[j] < responseWaterV + 5)) //mark water samples as green comparator[2] = 1; else comparator[2] = 0; // similar sky pixels on the water //count votes for (int i3=0; i3 < 3; i3++) votesSum = votesSum + comparator[i3]; if (votesSum > 1) { I[x][y-6+j].h = 0; I[x][y-6+j].s = 255; I[x][y-6+j].v = 255; } votesSum = 0; } } if (y < Y-1) //5 use to be equal to pixelsNumber-1. y = y + 5; if (y > Y-1) y = Y-1; else if (y == Y-1) { //5 use to be equal to pixelsNumber-1 x = x + 1; y = 0; } // ix = 0; } /*********************************************************************/ for(int i = 0; i < 3; i++) { comparator[i] = 0; } //int counter = 0; column1 = 0; row1 = 0; x = boatFront->height/1.45; y = 0; while (x < X-1) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i<6;i++) { column1 = y+i; if (column1 > Y-1) column1 = Y-1; cvmSet(sampleHue,0,i,I[x][column1].h); cvmSet(sampleSat,0,i,I[x][column1].s); cvmSet(sampleVal,0,i,I[x][column1].v); } for (int i=0;i<6;i++) { for (int j=0;j<6;j++) { if ((minH < cvmGet(sampleHue,0,j)) && (maxH > cvmGet(sampleHue,0,j))) //mark water samples as green comparator[0] = 1; else comparator[0] = 0; if ((minS < cvmGet(sampleSat,0,j)) && (maxS > cvmGet(sampleSat,0,j))) //mark water samples as green comparator[1] = 1; else comparator[1] = 0; if ((minV < cvmGet(sampleVal,0,j)) && (maxV > cvmGet(sampleVal,0,j))) //mark water samples as red comparator[2] = 1; else comparator[2] = 0; //count votes for (int i3=0; i3 < 3; i3++) votesSum = votesSum + comparator[i3]; if (votesSum > 1) { //use the known water samples as new training data if((i<boatFront->height/xDivisor) && (j<boatFront->width/yDivisor)) { cvmSet(resampleHue,i,j,cvmGet(sampleHue,0,j)); cvmSet(resampleSat,i,j,cvmGet(sampleSat,0,j)); cvmSet(resampleVal,i,j,cvmGet(sampleVal,0,j)); } //6 use to be equal to pixelsNumber. I[x][y-6+j].h = 0; I[x][y-6+j].s = 255; I[x][y-6+j].v = 255; } votesSum = 0; } } if (y < Y-1) //5 use to be equal to pixelsNumber-1. y = y + 5; if (y > Y-1) y = Y-1; else if (y == Y-1) { //5 use to be equal to pixelsNumber-1 x = x + 1; y = 0; } //ix = 0; } /***************Deal with reflection*****************/ for(int i = 0; i < 3; i++) { comparator[i] = 0; } //int counter = 0; votesSum = 0; column1 = 0; row1 = 0; x = boatFront->height/1.45; y = 0; while (x < X-1) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i<6;i++) { column1 = y+i; if (column1 > Y-1) column1 = Y-1; cvmSet(sampleHue,0,i,I[x][column1].h); cvmSet(sampleSat,0,i,I[x][column1].s); cvmSet(sampleVal,0,i,I[x][column1].v); } for (int i=0;i<6;i++) { for (int j=0;j<6;j++) { if ((minH < cvmGet(sampleHue,0,j)) && (maxH > cvmGet(sampleHue,0,j))) //mark water samples as green comparator[0] = 1; else comparator[0] = 0; if ((0.8*255 > cvmGet(sampleSat,0,j)))// && (maxS < cvmGet(sampleSat,0,j))) //mark water samples as green comparator[1] = 1; else comparator[1] = 0; if ((0.6*255 < cvmGet(sampleVal,0,j)))// || (maxV < cvmGet(sampleVal,0,j))) //mark water samples as green comparator[2] = 1; else comparator[2] = 0; //count votes for (int i3=0; i3 < 3; i3++) votesSum = votesSum + comparator[i3]; if (votesSum > 1) { //use the known water samples as new training data if((i<boatFront->height/xDivisor) && (j<boatFront->width/yDivisor)) { cvmSet(resampleHue,i,j,cvmGet(sampleHue,0,j)); cvmSet(resampleSat,i,j,cvmGet(sampleSat,0,j)); cvmSet(resampleVal,i,j,cvmGet(sampleVal,0,j)); } //6 use to be equal to pixelsNumber. I[x][y-6+j].h = 0; I[x][y-6+j].s = 255; I[x][y-6+j].v = 255; } votesSum = 0; } } if (y < Y-1) //5 use to be equal to pixelsNumber-1. y = y + 5; if (y > Y-1) y = Y-1; else if (y == Y-1) { //5 use to be equal to pixelsNumber-1 x = x + 1; y = 0; } //ix = 0; } /**********Resample the entire patch**********/ /*********find a new min and max for a new sample range*************/ for(int i = 0; i < 3; i++) { comparator[i] = 0; } //int counter = 0; votesSum = 0; column1 = 0; row1 = 0; x = boatFront->height/1.45; y = 0; maxH = cvmGet(resampleHue,0,0); maxS = cvmGet(resampleSat,0,0); maxV = cvmGet(resampleVal,0,0); minH = cvmGet(resampleHue,0,0); minS = cvmGet(resampleSat,0,0); minV = cvmGet(resampleVal,0,0); for (int i=0; i < boatFront->height/xDivisor; i++) { for (int j=0; j < boatFront->width/yDivisor; j++) { if (cvmGet(resampleHue,i,j) > maxH) maxH = cvmGet(resampleHue,i,j); if (cvmGet(resampleSat,i,j) > maxS) maxS = cvmGet(resampleSat,i,j); if (cvmGet(resampleVal,i,j) > maxV) maxV = cvmGet(resampleVal,i,j); if (cvmGet(resampleHue,i,j) < minH) minH = cvmGet(resampleHue,i,j); if (cvmGet(resampleSat,i,j) < minS) minS = cvmGet(resampleSat,i,j); if (cvmGet(resampleVal,i,j) < minV) minV = cvmGet(resampleVal,i,j); } } while (x < X-1) { for (int i=0;i<6;i++) { for (int j=0;j<6;j++) { if ((minH < I[x][y-6+j].h) && (maxH > I[x][y-6+j].h)) //mark water samples as red I[x][y-6+j].h = 0; else comparator[0] = 0; if ((minS < I[x][y-6+j].s) && (maxS > I[x][y-6+j].s)) //mark water samples as red I[x][y-6+j].s = 255; else comparator[1] = 0; if ((minV < I[x][y-6+j].v) && (maxV > I[x][y-6+j].v)) //mark water samples as red I[x][y-6+j].v = 255; } } if (y < Y-1) //5 use to be equal to pixelsNumber-1. y = y + 5; if (y > Y-1) y = Y-1; else if (y == Y-1) { //5 use to be equal to pixelsNumber-1 x = x + 1; y = 0; } } //cout << "Sample data from current images" << endl; //for (int i = 0; i<20;i++) //{ // cout << "HUE: " << cvmGet(sampleHue,0,i) << endl; // cout << "Saturation: " << cvmGet(sampleSat,0,i) << endl; // cout << "Value: " << cvmGet(sampleVal,0,i) << endl; //} //traverse through the image one more time, divide the image in grids of // 500x500 pixels, and see how many pixels of water are in each grid. If // most of the pixels are labeled water, then mark all the other pixels // as water as well //int counter = 0; votesSum = 0; column1 = 0; row1 = 0; x = boatFront->height/1.45; y = 0; /***************Divide the picture in cells for filtering**********/ while (x < X-1) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i < boatFront->height/xDivisor; i++) { for(int j = 0; j < boatFront->width/yDivisor; j++) { cvmSet(resampleHue2,i,j,I[x+i][y+j].h); cvmSet(resampleSat2,i,j,I[x+i][y+j].s); cvmSet(resampleVal2,i,j,I[x+i][y+j].v); if(cvmGet(resampleHue2,i,j)==0 && cvmGet(resampleSat2,i,j)==255 && cvmGet(resampleVal2,i,j)==255) { votesSum++; } } } if (votesSum > (((boatFront->height/xDivisor)*(boatFront->width/yDivisor))*(4/5))) { // if bigger than 4/5 the total number of pixels in a square, then consider the entire thing as water // We might need to use other smaller quantities (like 5/6 maybe?) for (int i = 0; i < boatFront->height/xDivisor;i++) { for (int j = 0; j < boatFront->width/yDivisor; j++) { row1 = x + i; if (row1 > X-1) row1 = X-1; column1 = y+j; if (column1 > Y-1) column1 = Y-1; I[row1][column1].h = 0; I[row1][column1].s = 255; I[row1][column1].v = 255; } } } else { // If not water, eliminate all red pixels and turn those pixels // back to the original color for (int i = 0; i < boatFront->height/xDivisor;i++) { for (int j = 0; j < boatFront->width/yDivisor; j++) { row1 = x + i; if (row1 > X-1) row1 = X-1; column1 = y+j; if (column1 > Y-1) column1 = Y-1; I[row1][column1].h = IBackUp[row1][column1].h;//255;//IBackUp[row1][column1].h; I[row1][column1].s = IBackUp[row1][column1].s;//255;//IBackUp[row1][column1].s; I[row1][column1].v = IBackUp[row1][column1].v;//255;//IBackUp[row1][column1].v; } } } y = y + boatFront->width/xDivisor; if (y > Y-1) { x = x + boatFront->height/yDivisor; y = 0; } votesSum = 0; } /********************Isolate obstacles************************/ votesSum = 0; int paint = 0; column1 = 0; row1 = 0; x = boatFront->height/1.45; y = 0; xDiv = 20; yDiv = 20; /***************Divide the picture in cells for filtering**********/ // Small pixel areas (noise) are going to be eliminated from the picture // living only the big obstacles while (x < X-2) { //get a random sample taken from the picture. Must be determined whether //it is water or ground for (int i = 0; i < boatFront->height/xDiv; i++) { for(int j = 0; j < boatFront->width/yDiv; j++) { row1 = x + i; if (row1 > X-2) row1 = X-2; column1 = y+j; if (column1 > Y-1) column1 = Y-1; cvmSet(resampleHue2,i,j,I[row1][column1].h); cvmSet(resampleSat2,i,j,I[row1][column1].s); cvmSet(resampleVal2,i,j,I[row1][column1].v); if(cvmGet(resampleHue2,i,j)==0 && cvmGet(resampleSat2,i,j)==255 && cvmGet(resampleVal2,i,j)==255) { votesSum++; } } } if (votesSum > (((boatFront->height/xDiv)*(boatFront->width/yDiv))*(4.5/5))) { // if bigger than 4/5 the total number of pixels in a square, then consider the entire thing as water // We might need to use other smaller quantities (like 5/6 maybe?) for (int i = 0; i < boatFront->height/xDiv;i++) { for (int j = 0; j < boatFront->width/yDiv; j++) { row1 = x + i; if (row1 > X-2) row1 = X-2; column1 = y+j; if (column1 > Y-1) column1 = Y-1; I[row1][column1].h = 0; I[row1][column1].s = 255; I[row1][column1].v = 255; } } } else { int count = 0; // If not water, eliminate all red pixels and turn those pixels // back to the original color for (int i = 0; i < boatFront->height/xDiv;i++) { for (int j = 0; j < boatFront->width/yDiv; j++) { row1 = x + i; if (row1 > X-2) row1 = X-2; column1 = y+j; if (column1 > Y-1) column1 = Y-1; I[row1][column1].h = IBackUp[row1][column1].h;//255; I[row1][column1].s = IBackUp[row1][column1].s;//255; I[row1][column1].v = IBackUp[row1][column1].v;//255; // count++; } } } y = y + boatFront->width/yDiv; if (y > Y-1) { x = x + boatFront->height/xDiv; if (x > X-2) x = X-2; y = 0; } votesSum = 0; } /****************Find Obstacles boundaries*********************************/ if( grayStorage == NULL ) { grayStorage = cvCreateMemStorage(0); } else { cvClearMemStorage(grayStorage); } backUpImage = cvCloneImage(boatFront); //convert from HSV to RGB cvCvtColor(boatFront, boatFront, CV_HSV2BGR); cvCvtColor(backUpImage, backUpImage, CV_HSV2BGR); //do flood fill for obstacles cvFloodFill( backUpImage, seed_point, color, cvScalarAll(255), cvScalarAll(2), NULL, 8, NULL); //convert to to gray to do more obstacle segmentation cvCvtColor(backUpImage, grayImage, CV_BGR2GRAY); //convert to binary cvThreshold(grayImage, bwImage, 100, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); //eliminate small unnecessary pixel areas //bwImage is a pointer, so no need to reuse findCountours int findCountours = bwareaopen_(bwImage, 100); //find contours of obstacles in image cvFindContours(bwImage, grayStorage, &contours); cvZero( bwImage ); //redraw clean contours for( CvSeq* c=contours; c!=NULL; c=c->h_next) { cvDrawContours(bwImage, c, cvScalarAll(255), cvScalarAll(255), 8); cout << "Contour area: " << cvContourArea(c, CV_WHOLE_SEQ) << endl; //area in pixels //find the x,y coordinate of the center of a contour cvMoments(c, &moment, 0); //centroid/moment of the contour/obstacle //cout << "Contour center: " << moment.m10/moment.m00 << ", " << moment.m01/moment.m00 << endl; //The distance formula calculated by plotting points is given by: /*********** distance = 0.1622208546*pow(1.0186851612,pixels) *****************/ /*********** pixel = 87.0413255*pow(distance,0.4062956891) *****************/ //These formulas only work for 640X480 images // x,y coordinates of the obstacle from the bottom center of the image //Ignore everything less than 0.3 meters apart (anything too close to the boat) //if ((X - (row1 -(boatFront->height/xDiv)/2)) > (87.0413255*pow(0.3,0.4062956891))) //{ xObstacleDistance = 0.1622208546*pow(1.0186851612,X - (moment.m10/moment.m00)); if (xObstacleDistance == 0.0) //try to ignore obstacle that are too close xObstacleDistance = 0.01; //robot shall tell operator if there is //a problem with a close by obstacle yObstacleDistance = 0.1622208546*pow(1.0186851612,Y/2 - (moment.m01/moment.m00)); //obstacle distance obstacleDistance = sqrt(pow(xObstacleDistance,2) + pow(yObstacleDistance,2)); //obstacle heading obstacleHeading = tan((yObstacleDistance/xObstacleDistance)*PI/180); cout << "Obstacle polar coordinates: " << endl; cout << "x: " << xObstacleDistance << " Y: " << yObstacleDistance << endl; cout << "Distance (meters) " << obstacleDistance << endl; cout << "Direction (degrees): " << obstacleHeading << endl << endl; //} } /**************************************************************************/ try { //fprintf(stderr,"\n boatFront\n"); cvShowImage("Boat Front", boatFront); //cvShowImage("Color Segment", backUpImage); //cvShowImage("Obstacles", bwImage); } catch (sensor_msgs::CvBridgeException& e) { ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str()); } }