コード例 #1
0
void BlockEdgeDetectorT::getContoursLeftRight(cv::Mat binaryImage, vector<cv::Point2f>& contour)
{
	cv::Mat img = binaryImage;
	int imgwidth = img.cols;
	int imgheight = img.rows;
	//边界追踪
	cv::Point startpoint;
	//寻找第一个点
	for (int i = 0; i < imgheight; i++)//行
	{
		bool flag = 0;
		//循环查找边界
		for (int j = imgwidth - 1; j > 0; j--)//列
		{
			if (img.ptr<uchar>(i)[j] > 0)
			{
				startpoint.y = i;
				startpoint.x = j;
				flag = 1;
				break;
			}
		}
		if (flag)
			break;
	}

	contour.clear();
	contour.push_back(startpoint);
	cv::Point v[8];
	v[0] = cv::Point(-1, -1);//左上
	v[1] = cv::Point(0, -1);//上
	v[2] = cv::Point(1, -1);//右上
	v[3] = cv::Point(1, 0);//右
	v[4] = cv::Point(1, 1);//右下
	v[5] = cv::Point(0, 1);//下
	v[6] = cv::Point(-1, 1);//左下
	v[7] = cv::Point(-1, 0);//左
	while (true)
	{
		cv::Point lastpoint(contour[contour.size() - 1]);
		cv::Point lastlastpoint = lastpoint;
		if (contour.size() > 1)
			lastlastpoint = contour[contour.size() - 2];

		//追到边界时退出
		if (lastpoint.x  == 0 || lastpoint.x == (imgwidth - 1) || lastpoint.y == (imgheight - 1))
			break;

		//寻找上一点的右边那一点(八邻域范围)
		int start = 0;
		for (int i = 0; i < 8; i++)
		{
			if ((lastpoint + v[i]) == lastlastpoint)
			{
				if (i == 7)
					start = 0;
				else
					start = i + 1;
				break;
			}
		}

		int count = 0;
		bool flag = 0;//当取到v[7]时,表示边界追踪开始往左,则退出。
		while (true)
		{
			int i = count + start;
			if (i >= 8) i -= 8;
			cv::Point nextpoint = lastpoint + v[i];
			if (//nextpoint != lastlastpoint &&
				nextpoint.x >= 0 && nextpoint.y >= 0 &&
				nextpoint.x < imgwidth && nextpoint.y < imgheight &&
				img.ptr<uchar>(nextpoint.y)[nextpoint.x] > 0)
			{
				if (i == 7)
					flag = 1;
				contour.push_back(nextpoint);
				break;
			}
			count++;
			if (count >= 8)
				break;
		}

		if (flag)
			break;
	}
	//平滑滤波
	//for (size_t i = 1; i < contour.size() - 1; i++)
	//{
	//	contour[i].x = (contour[i - 1].x + contour[i + 1].x) / 2;
	//	contour[i].y = (contour[i - 1].y + contour[i + 1].y) / 2;
	//}
	//for (size_t i = 1; i < contour.size() - 1; i++)
	//{
	//	contour[i].x = (contour[i - 1].x + contour[i + 1].x) / 2;
	//	contour[i].y = (contour[i - 1].y + contour[i + 1].y) / 2;
	//}



	//for (int i = 0; i < contour.size(); i++)
	//{
	//	contour[i].y = 30 + contour[i].y - ((int)(p_block->UpLine.k*(i - 0)) + contour[0].y);
	//}

#ifdef BED_OUTPUT_DEBUG_INFO
	//验证绘图
	cv::Mat draw(imgheight, imgwidth, CV_8U, cv::Scalar(0));
	for (int i = 0; i < contour.size(); i++)
	{
		draw.ptr<uchar>((int)contour[i].y)[(int)contour[i].x] = 255;
	}
#endif

	int s = contour.size();
}
コード例 #2
0
ファイル: mesh.cpp プロジェクト: uranix/aniaft-rewrite
// splits points with more than 7 neibs
void Mesh::splitVertex() {
    for (int i = 0; i < (int)pts.size(); i++){
        Vertex &p = pts[i];
        int n1 = p.neib.size();
        if( n1 <= 7 )
            continue;
        int n2 = n1/2;
        n1 = n1 - n2;
        sortNeigbor(i);

        const Vertex &p2 = pts[p.neib[0]];

//        double size = sizeFace(p.x, p.y);
        double size = Metric::distance(p.x, p.y, p2.x, p2.y);

        addVertex(p.x+0.1*size, p.y);
        Vertex &pv = pts.back();
        int vert = lastpoint();

        pv.neib.push_back(-1);

        for (const int nei : p.neib) {
            Vertex &pn = pts[nei];
            if (!pn.skip_neib) {
                pn.neib.clear();
                pn.neib.push_back(-1);
            }
        }

        int lab = -1;
        for(int j = 0; j < n1 - 1; j++) {
            Triangle &tr = tri[p.neibTria[j]];
            if (lab == -1)
                lab = tr.label;

            if (lab != tr.label)
                throw std::logic_error("aniAFT: different materials inside region");
            changeTria(p.neibTria[j], p.neib[j+1], p.neib[j], i);
        }
        for(int j = n1; j < n1 + n2 - 1; j++) {
            Triangle &tr = tri[p.neibTria[j]];
            if (lab != tr.label)
                throw std::logic_error("aniAFT: different materials inside region");
            changeTria(p.neibTria[j], p.neib[j+1], p.neib[j], vert);
        }
        {
            int it = p.neibTria[n1 - 1];
            Triangle &tr = tri[it];
            if (lab != tr.label)
                throw std::logic_error("aniAFT: different materials inside region");

            changeTria(it, p.neib[n1-1], i, vert);
        }
        {
            int it = p.neibTria[n1 + n2 - 1];
            Triangle &tr = tri[it];
            if (lab != tr.label)
                throw std::logic_error("aniAFT: different materials inside region");
            changeTria(it, p.neib[n1], p.neib[n1-1], vert);
        }
        addTria(p.neib[n1+n2-1], vert, i, lab);
        addTria(p.neib[n1+n2-1], i, p.neib[0],lab);
    }
    calcNeigTria();
    calcNeigbor();

    for(int i=0; i<5; i++)
        smoothing();
}
コード例 #3
0
ファイル: Agent.cpp プロジェクト: JennaMalkin/openc2e
// Creatures 2 collision finding
void Agent::findCollisionInDirection(unsigned int i, class MetaRoom *m, Point src, int &dx, int &dy, Point &deltapt, double &delta, bool &collided, bool followrooms) {
	src.x = (int)src.x;
	src.y = (int)src.y;

	if (m->wraparound()) {
		if (src.x > m->x() + m->width() || (dx > 0 && src.x == m->x() + m->width())) src.x -= m->width();
		else if (src.x < m->x() || (dx < 0 && src.x == m->x())) src.x += m->width();
	}

	// TODO: caching rooms affects behaviour - work out if that's a problem
	shared_ptr<Room> room = roomcache[i].lock();
	if (!room || !room->containsPoint(src.x, src.y)) {
		room = bestRoomAt(src.x, src.y, i, m, shared_ptr<Room>());
		roomcache[i] = room;
	}

	if (!room) { // out of room system
		if (!displaycore)
			unhandledException(boost::str(boost::format("out of room system at (%f, %f)") % src.x % src.y), false);
		falling = false;
		displaycore = true;
		return;
	}

	int lastdirection = 0;

	bool steep = abs(dy) > abs(dx);

	int signdx = dx < 0 ? -1 : 1;
	int signdy = dy < 0 ? -1 : 1;

	Line l(Point(0,0),Point(dx,dy));

	Point lastpoint(0,0);

	Vehicle *vehicle = 0;
	if (invehicle) vehicle = dynamic_cast<Vehicle *>(invehicle.get());

	for (int loc = 0; loc <= abs(steep ? dy : dx); loc++) {
		Point p = steep ? l.pointAtY(loc*signdy) : l.pointAtX(loc*signdx);
		p.x = (int)p.x;
		p.y = (int)p.y;

		if (vehicle) {
			if (src.x + p.x < vehicle->x + vehicle->cabinleft) {
				lastdirection = 0;
				collided = true;
				break;
			}
			if (src.x + p.x > vehicle->x + vehicle->cabinright) {
				lastdirection = 1;
				collided = true;
				break;
			}
			if (src.y + p.y < vehicle->y + vehicle->cabintop) {
				lastdirection = 2;
				collided = true;
				break;
			}
			if (src.y + p.y > vehicle->y + vehicle->cabinbottom) {
				lastdirection = 3;
				collided = true;
				break;
			}

			lastpoint = p;

			continue;
		}

		bool trycollisions = false;

		bool endofroom = false;
	
		if (src.x + p.x < room->x_left) {
			if (i != 1 && dx < 0) { trycollisions = true; lastdirection = 0; }
			endofroom = true;
		}
		if (src.x + p.x > room->x_right) {
			if (i != 0 && dx > 0) { trycollisions = true; lastdirection = 1; }
			endofroom = true;
		}
		if (src.y + p.y < room->y_left_ceiling) {
			if (i != 3 && dy < 0) { trycollisions = true; lastdirection = 2; }
			endofroom = true;
		}
		if (src.y + p.y > room->y_left_floor) {
			if (i != 2 && dy > 0) { trycollisions = true; lastdirection = 3; }
			endofroom = true;
		}

		// find the next room, if necessary, and work out whether we should move into it or break out
		if (endofroom) {
			if (m->wraparound()) {
				if (dx > 0 && src.x + p.x >= m->x() + m->width()) src.x -= m->width();
				else if (dx < 0 && src.x + p.x <= m->x()) src.x += m->width();
			}

			shared_ptr<Room> newroom = bestRoomAt(src.x + p.x, src.y + p.y, i, m, room);

			bool collision = false;

			// collide if we're out of the room system
			if (!newroom) {	collision = true; }
			// collide if there's no new room connected to this one
			else if (room->doors.find(newroom) == room->doors.end()) { collision = true; }
			// collide if the PERM between this room and the new room is smaller than or equal to our size
			else if (size.getInt() > room->doors[newroom]->perm) { collision = true; }

			if (collision && (trycollisions || (!newroom))) {
				collided = true;
				break;
			}

			// move to the new room and keep going!
			room = newroom;
		}
	
		if (room->floorpoints.size() && i == 3 && dy >= 0 && size.getInt() > room->floorvalue.getInt()) { // TODO: Hack!
			// TODO: we don't check floorYatX isn't returning a 'real' room floor, but floorpoints should cover the whole floor anyway
			int floory = room->floorYatX(src.x + p.x);
			
			// never collide when the top point of an object is below the floor.
			Point top = boundingBoxPoint(2);

			// TODO: consider steep floors
			if (src.y + p.y > floory && top.y < floory) {
				collided = true;
				lastdirection = 3;
				break;
			}
		}
		
		if ((!followrooms) && endofroom) break;

		lastpoint = p;
	}

	double length2 = (lastpoint.x * lastpoint.x) + (lastpoint.y * lastpoint.y);
	if (length2 < delta) {
		// TODO: !followrooms is a horrible way to detect a non-physics call
		if (collided && followrooms) lastcollidedirection = lastdirection;
		deltapt = lastpoint;
		delta = length2;
	}
}
コード例 #4
0
ファイル: drvlplot.cpp プロジェクト: neonquill/pstoedit
// print a path via a sequence of fline(), fcont(), fbezier3() operations,
// terminating with a final endpath()
void drvplot::print_coords()
{
	Point lastpoint(0, 0);
	const Point & firstpoint = pathElement(0).getPoint(0);
	bool currently_at_lastpoint = false;
	bool last_was_endpath = false;

	// since libplot/libplotter doesn't (yet) support sub-paths,
	// all paths that we draw will be of the form
	// moveto {lineto,curveto}+  {closepath}
	// where {}+ means one or more repetitions, and {} means optional.

	for (unsigned int n = 0; n < numberOfElementsInPath(); n++) {
		const basedrawingelement & elem = pathElement(n);
		switch (elem.getType()) {
		case moveto:
			{
				const Point & p = elem.getPoint(0);
				lastpoint = p;
				currently_at_lastpoint = false;
				last_was_endpath = false;
			}
			break;
		case lineto:
			{
				const Point & p = elem.getPoint(0);
				if (currently_at_lastpoint)
					(void)plotter->fcont(p.x_ + x_offset, p.y_ + y_offset);
				else
					(void)plotter->fline(lastpoint.x_ + x_offset,
								   lastpoint.y_ + y_offset, p.x_ + x_offset, p.y_ + y_offset);
				lastpoint = p;
				currently_at_lastpoint = true;
				last_was_endpath = false;
			}
			break;
		case curveto:
			{
				const Point & p1 = lastpoint;
				const Point & p2 = elem.getPoint(0);
				const Point & p3 = elem.getPoint(1);
				const Point & p4 = elem.getPoint(2);

				(void)plotter->fbezier3(p1.x_ + x_offset, p1.y_ + y_offset,
								  p2.x_ + x_offset, p2.y_ + y_offset,
								  p3.x_ + x_offset, p3.y_ + y_offset,
								  p4.x_ + x_offset, p4.y_ + y_offset);
				lastpoint = p4;
				currently_at_lastpoint = true;
				last_was_endpath = false;
			}
			break;
		case closepath:
			if (currently_at_lastpoint)
				/* have drawn at least one segment */
			{
				(void)plotter->fcont(firstpoint.x_ + x_offset, firstpoint.y_ + y_offset);
				(void)plotter->endpath();
				currently_at_lastpoint = true;
				last_was_endpath = true;
			}
			break;
		default:
			errf << "\t\tFatal: unexpected case in drvlplot " << endl;
			abort();
			break;
		}
	}
	if (last_was_endpath == false)
		(void)plotter->endpath();
}