Ejemplo n.º 1
0
/*public*/
void
LineIntersector::computeIntersection(const Coordinate& p1,const Coordinate& p2,const Coordinate& p3,const Coordinate& p4)
{
	inputLines[0][0]=&p1;
	inputLines[0][1]=&p2;
	inputLines[1][0]=&p3;
	inputLines[1][1]=&p4;
	result=computeIntersect(p1,p2,p3,p4);
	//numIntersects++;
}
Ejemplo n.º 2
0
void computeIntersectList(std::vector<cv::Vec4i>& linesH,
                          std::vector<cv::Vec4i>& linesV, 
                          std::vector<cv::Point2f>& interPoints)
{
  // Calculate Intersections between Horizontal and Vertical Lines
  interPoints.reserve(linesH.size() * linesV.size() / 10);
  for (size_t i = 0; i < linesH.size(); i++)
  {
    for (size_t j = 0; j < linesV.size(); j++)
    {
      cv::Point2f point = computeIntersect(linesH[i], linesV[j]);
      if (point != cv::Point2f(-1, -1))
        interPoints.push_back(point);
    }
  }
}
Ejemplo n.º 3
0
	int find_corners(cv::Mat& contour, unsigned thresh,std::vector<cv::Point2f>& _corners){
	  std::vector<std::vector<cv::Point> > contours;
	  std::vector<cv::Vec4i> hierarchy;
	  std::vector<cv::Vec4i> lines;

	  cv::Mat gray;
	  cv::cvtColor( contour, gray, CV_RGB2GRAY );
	  cv::HoughLinesP(gray, lines, 1, CV_PI/180, thresh, 30, 10);   // Преобразованием Hough находим только прямые линии. получаем вектор lines (x1,y1,x2,y2)
	  
	  std::vector<cv::Point2f> corners;
	  for (int i = 0; i < lines.size(); i++){
	    for (int j = i+1; j < lines.size(); j++)    {
	        cv::Point2f pt = computeIntersect(lines[i], lines[j]);
	        if (pt.x >= 0 && pt.y >= 0)
	            corners.push_back(pt);
	    }
	  }
	  	  
	  std::cout << lines.size()<<" : "<<corners.size() << std::endl;
	  for (std::vector<cv::Point2f>::const_iterator i = corners.begin();i != corners.end(); ++i){
	    std::cout << *i << std::endl;
	  }
	  
	  std::cout << "Counting" << std::endl;
	  aproxCorners(corners);
	  std::cout << "New" << std::endl;
	  
	  for (std::vector<cv::Point2f>::const_iterator i = corners.begin();i != corners.end(); ++i){
	    std::cout << *i << std::endl;
	  }


	  cv::Point2f center(0,0);
	  for (int i = 0; i < corners.size(); i++)
	    center += corners[i];
	  center *= (1. / corners.size());

	  _corners.clear();
	  if ( sortCorners(corners, center) > -1){    
	  	_corners = corners;	
	  }else{
	  	return -1;
	  }
	  return 0;
	}
int main()
{
	cv::Mat src = cv::imread("assets/perspective-quadrilateral.jpg");
	if (src.empty())
		return -1;

	cv::Mat bw;
	cv::cvtColor(src, bw, CV_BGR2GRAY);
	cv::blur(bw, bw, cv::Size(3, 3));
	cv::Canny(bw, bw, 100, 100, 3);

	std::vector<cv::Vec4i> lines;
	cv::HoughLinesP(bw, lines, 1, CV_PI/180, 70, 30, 10);

	// Expand the lines
	for (int i = 0; i < lines.size(); i++)
	{
		cv::Vec4i v = lines[i];
		lines[i][0] = 0;
		lines[i][1] = ((float)v[1] - v[3]) / (v[0] - v[2]) * -v[0] + v[1]; 
		lines[i][2] = src.cols; 
		lines[i][3] = ((float)v[1] - v[3]) / (v[0] - v[2]) * (src.cols - v[2]) + v[3];
	}
	
	std::vector<cv::Point2f> corners;
	for (int i = 0; i < lines.size(); i++)
	{
		for (int j = i+1; j < lines.size(); j++)
		{
			cv::Point2f pt = computeIntersect(lines[i], lines[j]);
			if (pt.x >= 0 && pt.y >= 0)
				corners.push_back(pt);
		}
	}

	std::vector<cv::Point2f> approx;
	cv::approxPolyDP(cv::Mat(corners), approx, cv::arcLength(cv::Mat(corners), true) * 0.02, true);

	if (approx.size() != 4)
	{
		std::cout << "The object is not quadrilateral!" << std::endl;
		return -1;
	}

	// Get mass center
	for (int i = 0; i < corners.size(); i++)
		center += corners[i];
	center *= (1. / corners.size());

	sortCorners(corners, center);

	cv::Mat dst = src.clone();

	// Draw lines
	for (int i = 0; i < lines.size(); i++)
	{
		cv::Vec4i v = lines[i];
		cv::line(dst, cv::Point(v[0], v[1]), cv::Point(v[2], v[3]), CV_RGB(0,255,0));
	}

	// Draw corner points
	cv::circle(dst, corners[0], 3, CV_RGB(255,0,0), 2);
	cv::circle(dst, corners[1], 3, CV_RGB(0,255,0), 2);
	cv::circle(dst, corners[2], 3, CV_RGB(0,0,255), 2);
	cv::circle(dst, corners[3], 3, CV_RGB(255,255,255), 2);

	// Draw mass center
	cv::circle(dst, center, 3, CV_RGB(255,255,0), 2);

	cv::Mat quad = cv::Mat::zeros(300, 220, CV_8UC3);

	std::vector<cv::Point2f> quad_pts;
	quad_pts.push_back(cv::Point2f(0, 0));
	quad_pts.push_back(cv::Point2f(quad.cols, 0));
	quad_pts.push_back(cv::Point2f(quad.cols, quad.rows));
	quad_pts.push_back(cv::Point2f(0, quad.rows));

	cv::Mat transmtx = cv::getPerspectiveTransform(corners, quad_pts);
	cv::warpPerspective(src, quad, transmtx, quad.size());

	cv::imshow("image", dst);
	cv::imshow("quadrilateral", quad);
	cv::waitKey();
	return 0;
}
Ejemplo n.º 5
0
///////////////////////////////////////////////////////////////////
// Panel::CannyDetection() 
// Description: This function is called by DetectEdges() and it
//  is the Canny edge detection function which does not contain
//  debugging statements. We run the image through several different 
//  image processing functions to prepare the image before edge
//  detection. After detection the edges we run Hough lines which 
//  approximates lines of minimum length as specified in 
//  Settings.xml. We find all intersections of the Hough lines 
//  then make a minimum area rectangle around the intersections to 
//  approximate the edges of the panel which we are trying to
//  measure. From there we use the unit conversion calculated 
//  in DetectFeatures() to find a length and width of the current
//  panel. We report the length and width with a message box. 
///////////////////////////////////////////////////////////////////
Mat Panel::CannyDetection(Mat image, bool showImg)
{
	Mat greyImage;
	cvtColor(image, greyImage, CV_BGR2GRAY);

	Mat eroded, dilated, thresh, blurredThresh, edges, edgesGray;
	vector<Vec2f> lines;

		threshold(greyImage, thresh, m_lowCannyThreshold, 255, THRESH_BINARY);
		erode(thresh, eroded, Mat());
		dilate(eroded, dilated, Mat());
		GaussianBlur(thresh, blurredThresh, Size(7, 7), m_sigmaX, m_sigmaY);
		Canny(blurredThresh, edges, m_cannyLow, m_cannyLow*m_ratio, 3);
		HoughLines(edges, lines, 1, CV_PI / 180, m_houghLength, 0, 0);

		cvtColor(edges, edgesGray, CV_GRAY2BGR);
		for (size_t i = 0; i < lines.size(); i++)
		{
			float rho = lines[i][0], theta = lines[i][1];
			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));
			line(edgesGray, pt1, pt2, Scalar(0, 0, 255), 3, CV_AA);
		}

		////////////////////////////////////////////////////////
		// Compute the intersection from the lines detected
		////////////////////////////////////////////////////////
		vector<Point2f> intersections;
		for (size_t i = 0; i < lines.size(); i++)
		{
			for (size_t j = 0; j < lines.size(); j++)
			{
				Vec2f line1 = lines[i];
				Vec2f line2 = lines[j];
				if (acceptLinePair(line1, line2, (float)CV_PI / 32))
				{
					Point2f intersection = computeIntersect(line1, line2);
					if (intersection.x >= 0 && intersection.y >= 0)
						intersections.push_back(intersection);
				}
			}
		}

		if (intersections.size() > 0)
		{
			vector<Point2f>::iterator i;
			for (i = intersections.begin(); i != intersections.end(); ++i)
			{
				cout << "Intersection is " << i->x << ", " << i->y << endl;
				circle(image, *i, 2, Scalar(0, 255, 0), 3);
			}
			// Find the minimum bounding rectangle
			RotatedRect rect;
			Point2f rectPoints[4];
			Scalar color = Scalar(255, 0, 0);
			if (intersections.size() == 4)
			{
				// TODO
			}
			rect = minAreaRect(intersections);
			rect.points(rectPoints);
			int j = 0;
			for (j; j < 4; j++)
				line(image, rectPoints[j], rectPoints[(j + 1) % 4], color, 5, 8);

			float topLength = (float)norm(rectPoints[1] - rectPoints[0]);
			float botLength = (float)norm(rectPoints[3] - rectPoints[2]);
			float panelWidthPixels = topLength < botLength ? topLength : botLength;

			float leftHeight = (float)norm(rectPoints[3] - rectPoints[0]);
			float rightHeight = (float)norm(rectPoints[2] - rectPoints[1]);
			float panelHeightPixels = leftHeight < rightHeight ? leftHeight : rightHeight;

			string dimensionDisplayPixels = "Pixels:\nWidth: " + to_string(panelWidthPixels) + " pixels\nHeight: " + to_string(panelHeightPixels) + " pixels";
			// ShowMessage(dimensionDisplayPixels);
			if (m_conversionRate)
			{
				float panelWidthReal = panelWidthPixels / m_conversionRate;
				float panelHeightReal = panelHeightPixels / m_conversionRate;
				string dimensionDisplayActual = "Actual:\nWidth: " + to_string(panelWidthReal) + " cm\nHeight: " + to_string(panelHeightReal) + " cm";
				ShowMessage(dimensionDisplayActual);
			}

		}

		if (showImg){
			namedWindow("Intersections", CV_WINDOW_KEEPRATIO);
			imshow("Intersections", image);
		}
		/////////////////////////////////////////////////////////////
		// End of Computing the intersection from the lines detected
		/////////////////////////////////////////////////////////////
	return edges;
}