#include "fork_rs.h" namespace graft_cv{ CForkDetectOptimal::CForkDetectOptimal() :m_roi_width(0),m_roi_height(0) { } CForkDetectOptimal::CForkDetectOptimal(int w,int h) :m_roi_width(w),m_roi_height(h) { } CForkDetectOptimal::~CForkDetectOptimal(){} void CForkDetectOptimal::set_roi_size(int w,int h){ m_roi_width = w; m_roi_height = h; } void CForkDetectOptimal::get_roi_size(int &w,int &h){ w = m_roi_width; h = m_roi_height; } double CForkDetectOptimal::center_pt_index( const Mat& binimg, Point¢, double cut_angle //刀具切割角度 ) { double ratio = 0.0; RotatedRect centers_rect = RotatedRect(Point2f(0,0), Size2f(m_roi_width,m_roi_height), -cut_angle);//换算成顺时针角度 Point2f vertices[4]; centers_rect.points(vertices); Point2f left_cent = Point2f(cent.x + vertices[0].x, cent.y + vertices[0].y); Point2f right_cent = Point2f(cent.x + vertices[1].x, cent.y + vertices[1].y); RotatedRect left_rect = RotatedRect(left_cent, Size2f(m_roi_width,m_roi_height), -cut_angle); RotatedRect right_rect = RotatedRect(right_cent, Size2f(m_roi_width,m_roi_height), -cut_angle); double left_cnt = roi_object_size(binimg, left_rect); double right_cnt = roi_object_size(binimg, right_rect); ratio = left_cnt* left_cnt/right_cnt/(m_roi_width*m_roi_height); //imshow Mat tmp_img = binimg.clone(); Point2f vertices_left[4]; Point2f vertices_right[4]; left_rect.points(vertices_left); right_rect.points(vertices_right); for (int i = 0; i < 4; i++){ line(tmp_img, vertices_left[i], vertices_left[(i+1)%4], Scalar(128,255,0), 1); line(tmp_img, vertices_right[i], vertices_right[(i+1)%4], Scalar(200,255,0), 1); } circle(tmp_img,cent,5,Scalar(128,0,0)); return ratio; } double CForkDetectOptimal::roi_object_size( const Mat& binimg, RotatedRect &rrect) { double cnt = 1.0; Rect brect = rrect.boundingRect(); Point2f vertices[4]; rrect.points(vertices); //Mat tmp_img = Mat::zeros(binimg.rows,binimg.cols,CV_8UC1); for(int r = brect.y; r(r,c) = 255; if(r<0||r>binimg.rows-1){continue;} if(c<0||c>binimg.cols-1){continue;} if(binimg.at(r,c) >0){cnt+=1.0;} } } } return cnt; } bool CForkDetectOptimal::is_in_rrect( Point2f* ptf4, Point2f ptf, float fAngle) { Point2f ptf4Vector[4]; int nQuadrant[4] = {0}; fAngle *= CV_PI/180 *(-1); for(int idx=0;idx<4;idx++){ float fDifx = float(ptf.x - ptf4[idx].x); float fDify = float(ptf.y - ptf4[idx].y); int nDifx = fDifx * cos(fAngle) - fDify * sin(fAngle); int nDify = fDifx * sin(fAngle) + fDify * cos(fAngle); if(nDifx >=0 && nDify >=0) nQuadrant[0]++; if(nDifx < 0 && nDify >=0) nQuadrant[1]++; if(nDifx < 0 && nDify < 0) nQuadrant[2]++; if(nDifx > 0 && nDify < 0) nQuadrant[3]++; } int firstIdx = -1; int secIdx = -1; int countNum = 0; for(int idx=0;idx<4;idx++){ if(nQuadrant[idx] !=0){ if(firstIdx == -1){ firstIdx = idx; } else{ if(secIdx == -1 && firstIdx != -1){ secIdx = idx; } } countNum++; } } if(countNum <= 2){ if(abs(firstIdx - secIdx)==1 || abs(firstIdx - secIdx)==3 || (countNum==1 && (firstIdx==-1 || secIdx==-1))) { return false; } } return true; } };