std::vector<cv::MatND> computeProbImage(cv::Mat image, std::vector<cv::Rect> rectRoi, std::vector<cv::Mat> &hist, std::vector<bool> &detected) { int smin = 30; int vmin = 10; int vmax = 256; cv::Mat mask; cv::Mat hsv; cv::Mat hue; std::vector<cv::MatND> backProj; int channels[] = {0,0}; int hbins = 30; // Quantize the hue to 30 levels //int sbins = 32; // and the saturation to 32 levels int histSize = MAX( hbins, 2 ); //int histSizes[] = {hbins, sbins}; float hue_range[] = { 0, 180 }; // hue varies from 0 to 179, see cvtColor //float sat_range[] = { 0, 256 }; // saturation varies from 0 (black-gray-white) to const float* range = { hue_range }; // 255 (pure spectrum color) //const float* ranges = { hue_range, sat_range }; //double maxVal=0; backProj.resize(rectRoi.size()); hist.resize(rectRoi.size()); cv::cvtColor(image, hsv, CV_BGR2HSV); hue.create(hsv.size(), hsv.depth()); cv::mixChannels(&hsv, 1, &hue, 1, channels, 1); cv::inRange(hsv, cv::Scalar(0, smin, MIN(vmin,vmax)), cv::Scalar(180, 256, MAX(vmin, vmax)), mask); for(size_t i=0;i<rectRoi.size();i++) { if(!detected[i]) { cv::Mat roi(hue, rectRoi[i]); cv::Mat maskroi(mask, rectRoi[i]); cv::calcHist(&roi, 1, 0, maskroi, hist[i], 1, &histSize, &range, true, false); cv::normalize(hist[i], hist[i], 0, 255, cv::NORM_MINMAX); detected[i] = true; roi.release(); maskroi.release(); } cv::calcBackProject(&hue, 1, 0, hist[i], backProj[i], &range); backProj[i] &= mask; } return backProj; }
void FindObjectMain::process_camshift() { // Some user defined parameters int vmin = config.vmin; int vmax = config.vmax; int smin = config.smin; float hranges[] = { 0, 180 }; const float* phranges = hranges; // Create aligned, RGB images if(!object_image) { object_image = cvCreateImage( cvSize(object_image_w, object_image_h), 8, 3); } if(!scene_image) { scene_image = cvCreateImage( cvSize(scene_image_w, scene_image_h), 8, 3); } // Temporary row pointers unsigned char **object_rows = new unsigned char*[object_image_h]; unsigned char **scene_rows = new unsigned char*[scene_image_h]; for(int i = 0; i < object_image_h; i++) { object_rows[i] = (unsigned char*)(object_image->imageData + i * object_image_w * 3); } for(int i = 0; i < scene_image_h; i++) { scene_rows[i] = (unsigned char*)(scene_image->imageData + i * scene_image_w * 3); } // Transfer object & scene to RGB images for OpenCV if(!prev_object) prev_object = new unsigned char[object_image_w * object_image_h * 3]; // Back up old object image memcpy(prev_object, object_image->imageData, object_image_w * object_image_h * 3); BC_CModels::transfer(object_rows, get_input(object_layer)->get_rows(), 0, 0, 0, 0, 0, 0, object_x1, object_y1, object_w, object_h, 0, 0, object_w, object_h, get_input(object_layer)->get_color_model(), BC_RGB888, 0, 0, 0); BC_CModels::transfer(scene_rows, get_input(scene_layer)->get_rows(), 0, 0, 0, 0, 0, 0, scene_x1, scene_y1, scene_w, scene_h, 0, 0, scene_w, scene_h, get_input(scene_layer)->get_color_model(), BC_RGB888, 0, 0, 0); delete [] object_rows; delete [] scene_rows; // from camshiftdemo.cpp // Compute new object if(memcmp(prev_object, object_image->imageData, object_image_w * object_image_h * 3) || !hist.dims) { Mat image(object_image); Mat hsv, hue, mask; cvtColor(image, hsv, CV_RGB2HSV); int _vmin = vmin, _vmax = vmax; //printf("FindObjectMain::process_camshift %d\n", __LINE__); inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask); int ch[] = { 0, 0 }; hue.create(hsv.size(), hsv.depth()); mixChannels(&hsv, 1, &hue, 1, ch, 1); Rect selection = Rect(0, 0, object_w, object_h); trackWindow = selection; int hsize = 16; Mat roi(hue, selection), maskroi(mask, selection); calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); normalize(hist, hist, 0, 255, CV_MINMAX); } // compute scene Mat image(scene_image); Mat hsv, hue, mask, backproj; cvtColor(image, hsv, CV_RGB2HSV); int _vmin = vmin, _vmax = vmax; inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask); int ch[] = {0, 0}; hue.create(hsv.size(), hsv.depth()); mixChannels(&hsv, 1, &hue, 1, ch, 1); //printf("FindObjectMain::process_camshift %d %d %d\n", __LINE__, hist.dims, hist.size[1]); RotatedRect trackBox = RotatedRect( Point2f((object_x1 + object_x2) / 2, (object_y1 + object_y2) / 2), Size2f(object_w, object_h), 0); trackWindow = Rect(0, 0, scene_w, scene_h); if(hist.dims > 0) { calcBackProject(&hue, 1, 0, hist, backproj, &phranges); backproj &= mask; //printf("FindObjectMain::process_camshift %d\n", __LINE__); // if(trackWindow.width <= 0 || // trackWindow.height <= 0) // { // trackWindow.width = object_w; // trackWindow.height = object_h; // } trackBox = CamShift(backproj, trackWindow, TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); //printf("FindObjectMain::process_camshift %d\n", __LINE__); // if( trackWindow.area() <= 1 ) // { // int cols = backproj.cols; // int rows = backproj.rows; // int r = (MIN(cols, rows) + 5) / 6; // trackWindow = Rect(trackWindow.x - r, trackWindow.y - r, // trackWindow.x + r, trackWindow.y + r) & // Rect(0, 0, cols, rows); // } } // printf("FindObjectMain::process_camshift %d %d %d %d %d\n", // __LINE__, // trackWindow.x, // trackWindow.y, // trackWindow.width, // trackWindow.height); // Draw mask over scene if(config.draw_keypoints) { for(int i = 0; i < scene_h; i++) { switch(get_input(scene_layer)->get_color_model()) { case BC_YUV888: { unsigned char *input = backproj.data + i * scene_image_w; unsigned char *output = get_input(scene_layer)->get_rows()[i + scene_y1] + scene_x1 * 3; for(int j = 0; j < scene_w; j++) { output[0] = *input; output[1] = 0x80; output[2] = 0x80; output += 3; input++; } break; } } } } // Get object outline in the scene layer // printf("FindObjectMain::process_camshift %d %d %d %d %d %d\n", // __LINE__, // (int)trackBox.center.x, // (int)trackBox.center.y, // (int)trackBox.size.width, // (int)trackBox.size.height, // (int)trackBox.angle); double angle = trackBox.angle * 2 * M_PI / 360; double angle1 = atan2(-(double)trackBox.size.height / 2, -(double)trackBox.size.width / 2) + angle; double angle2 = atan2(-(double)trackBox.size.height / 2, (double)trackBox.size.width / 2) + angle; double angle3 = atan2((double)trackBox.size.height / 2, (double)trackBox.size.width / 2) + angle; double angle4 = atan2((double)trackBox.size.height / 2, -(double)trackBox.size.width / 2) + angle; double radius = sqrt(SQR(trackBox.size.height / 2) + SQR(trackBox.size.width / 2)); border_x1 = (int)(trackBox.center.x + cos(angle1) * radius) + scene_x1; border_y1 = (int)(trackBox.center.y + sin(angle1) * radius) + scene_y1; border_x2 = (int)(trackBox.center.x + cos(angle2) * radius) + scene_x1; border_y2 = (int)(trackBox.center.y + sin(angle2) * radius) + scene_y1; border_x3 = (int)(trackBox.center.x + cos(angle3) * radius) + scene_x1; border_y3 = (int)(trackBox.center.y + sin(angle3) * radius) + scene_y1; border_x4 = (int)(trackBox.center.x + cos(angle4) * radius) + scene_x1; border_y4 = (int)(trackBox.center.y + sin(angle4) * radius) + scene_y1; }
int _tmain(int argc, _TCHAR* argv[]) { int hmin=175, hmax=185, smin=65, smax=108, vmin=136, vmax=253; cv::VideoCapture cap; DCB dcb; DWORD byteswritten; char a[]="abcdefg"; HANDLE hPort; SerialInit(&hPort,&dcb); WriteFile( hPort, a, sizeof(a), &byteswritten, NULL); std::cout<<byteswritten; CloseHandle(hPort); exit(1); std::cout << "initial webcam..."; cap.open(0); if(!cap.isOpened()) { std::printf("err init webcam!"); std::getchar(); return 0; } std::cout << "OK\n"; cv::namedWindow("Raw",cv::WINDOW_AUTOSIZE); cv::namedWindow("Histrogram",cv::WINDOW_AUTOSIZE); cv::namedWindow("Filtered",cv::WINDOW_AUTOSIZE); cv::namedWindow("Setting",cv::WINDOW_AUTOSIZE); cv::setMouseCallback("Raw",onMouse,0); cv::createTrackbar("Hmin","Setting",&hmin,255,0); cv::createTrackbar("Hmax","Setting",&hmax,255,0); cv::createTrackbar("Smin","Setting",&smin,255,0); cv::createTrackbar("Smax","Setting",&smax,255,0); cv::createTrackbar("Vmin","Setting",&vmin,255,0); cv::createTrackbar("Vmax","Setting",&vmax,255,0); int keycode=-1; while(keycode!=27) { cv::Mat frame,hsv,hist,histshow; cv::Mat hue,sat,val; histshow=cv::Mat::zeros(CAM_X,CAM_Y,CV_8UC3); hue=cv::Mat::zeros(CAM_X,CAM_Y,CV_8UC1); sat=cv::Mat::zeros(CAM_X,CAM_Y,CV_8UC1); val=cv::Mat::zeros(CAM_X,CAM_Y,CV_8UC1); cv::Mat threshold=cv::Mat::zeros(CAM_X,CAM_Y,CV_8UC1); double tt=(double)cv::getTickCount(); cap >> frame; if(frame.empty()) { std::cout<<"err!!!"; cv::waitKey(0); break; } cv::cvtColor(frame,hsv,CV_BGR2HSV); //split channels cv::Mat out[]={hue,sat,val}; int channelmapping[]={0,0,1,1,2,2}; cv::mixChannels(&hsv,3,out,3,channelmapping,3); //end split channels /* frame.adjustROI( select_rect.y, select_rect.x+select_rect.height, select_rect.x, select_rect.x+select_rect.width); */ float histranges[] = {0,180}; const float* phistranges = histranges; int ch[]={0}; int histdim=64; cv::Mat mask; cv::Mat roi(hue,select_rect); cv::Mat maskroi(mask,select_rect); cv::calcHist(&roi,1,0,maskroi,hist,1,&histdim,&phistranges,true,false); //threshold cv::inRange(hue,hmin,hmax,hue); cv::inRange(sat,smin,smax,sat); cv::inRange(val,vmin,vmax,val); //end threshold //and cv::bitwise_and(hue,sat,threshold,hue); cv::bitwise_and(threshold,val,threshold,val); //end and //erode&dilate cv::erode(threshold,threshold,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3)),cv::Point(-1,-1),1,0); cv::dilate(threshold,threshold,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(5,5)),cv::Point(-1,-1),10,0); //end erode&dilate //find corner std::vector<cv::Point2f> eig; cv::goodFeaturesToTrack(threshold,eig,50,0.01,10,cv::Mat(),3,false,0.04); cv::cornerSubPix(threshold,eig,cv::Size(10,10),cv::Size(-1,-1),cv::TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); cv::Point obj_origin; cv::Point obj_corner; cv::Rect obj_rect; obj_origin.x=(int)eig[0].x; obj_origin.y=(int)eig[0].y; obj_corner.x=(int)eig[0].x; obj_corner.y=(int)eig[0].y; for(int i=0;i<(int)eig.size();i++) { obj_origin.x=MIN(obj_origin.x,(int)eig[i].x); obj_origin.y=MIN(obj_origin.y,(int)eig[i].y); obj_corner.x=MAX(obj_corner.x,(int)eig[i].x); obj_corner.y=MAX(obj_corner.y,(int)eig[i].y); cv::circle(frame,eig[i],1,cv::Scalar(255,0,0),1,8,0); } obj_rect.x=obj_origin.x; obj_rect.y=obj_origin.y; obj_rect.width=abs(obj_rect.x-obj_corner.x); obj_rect.height=abs(obj_rect.y-obj_corner.y); //end find corner cv::rectangle(frame,obj_rect,cv::Scalar(0,0,255),1,8,0); cv::rectangle(frame,select_rect,cv::Scalar(0,255,0),1,8,0); cv::imshow("Raw",frame); cv::imshow("Filtered",threshold); tt=(double)cv::getTickCount()-tt; tt=tt/cv::getTickFrequency()*1000; std::cout<< "t:" << tt << "ms\n"; keycode=cv::waitKey(1); } std::cout << keycode; cv::destroyWindow("Raw"); cv::destroyWindow("Histrogram"); cv::destroyWindow("Filtered"); cv::destroyWindow("Setting"); cv::waitKey(0); return 0; }