【opencv】opencv图像透视变换和二值化处理

#include "highgui.h"
#include <opencv\cv.h>
#include "cv.h"
#include <cv.h>
#include <cvaux.h>
#include <highgui.h> 
#include <ml.h>
using namespace cv;

#define max(a,b)  (((a) > (b)) ? (a) : (b))  
#define min(a,b)  (((a) < (b)) ? (a) : (b))  

#define ROAD "H:\kc.jpg"
#define WIN1 "win1"
#define WIDTH 300
#define HEIGHT 300

int mouse_x,mouse_y; 
int pointset[8];

void point(int mouseevent, int x, int y, int flags, void* param) ;
void getPoint(const char* win) ;
void get_four_points(int *pointset,IplImage* crw);
void PerspectiveTrans(IplImage* src, IplImage* dst,int* pointset ,CvMat *transmat);
void invert_to_binary(IplImage* img);

template<class T> class Image {
	public:
	IplImage* imgp;

	Image(IplImage* img=0) {imgp=img;}
	~Image(){imgp=0;}
	inline T* operator[](const int rowIndx) {return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
};


typedef Image<unsigned char> BwImage;

void cvThin (IplImage* src, IplImage* dst, int iterations) 
{
	cvCopyImage(src, dst);
	BwImage dstdat(dst);
	IplImage* t_image = cvCloneImage(src);
	BwImage t_dat(t_image);
	for (int n = 0; n < iterations; n++)
	for (int s = 0; s <= 1; s++) 
	{
		cvCopyImage(dst, t_image);
		for (int i = 0; i < src->height; i++)
		for (int j = 0; j < src->width; j++)
		if (t_dat[i][j]) 
		{
			int a = 0, b = 0;
			int d[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1},{1, 0}, {1, -1}, {0, -1}, {-1, -1}};
			int p[8];
			p[0] = (i == 0) ? 0 : t_dat[i-1][j];
			for (int k = 1; k <= 8; k++) 
			{
				if (i+d[k%8][0] < 0 || i+d[k%8][0] >= src->height || j+d[k%8][1] < 0 || j+d[k%8][1] >= src->width)
					p[k%8] = 0;
				else 
					p[k%8] = t_dat[ i+d[k%8][0] ][ j+d[k%8][1] ];
				if (p[k%8]) 
				{
					b++;
					if (!p[k-1]) a++;
				}
			}
			if (b >= 2 && b <= 6 && a == 1)
			if (!s && !(p[2] && p[4] && (p[0] || p[6])))
				dstdat[i][j] = 0;
			else 
				if (s && !(p[0] && p[6] && (p[2] || p[4])))
					dstdat[i][j] = 0;
		}
	}
	cvReleaseImage(&t_image);
};
int main()
{
	
	IplImage* crw = cvLoadImage(ROAD); //定义一个图像指针,后面将指向获取的图像
	IplImage* transming		= cvCreateImage(cvSize(WIDTH,HEIGHT),IPL_DEPTH_8U,3);
	CvMat *transmat		 = cvCreateMat(3, 3, CV_32FC1);

	cvNamedWindow(WIN1); //新建一个窗口用于显示图像
	//CvMat* transmat = cvCreateMat(3,3,CV_32FC1);
	cvShowImage(WIN1, crw);
	


	get_four_points(pointset,crw);
	PerspectiveTrans(crw,transming,pointset,transmat);

	cvNamedWindow("PerspectiveTrans");
	cvShowImage("PerspectiveTrans", transming);

	invert_to_binary(transming);
	cvNamedWindow("binary");
	cvShowImage("binary", transming);

	cvThin(transming,transming,100);
	cvNamedWindow("thin");
	cvShowImage("thin", transming);

	cvWaitKey(0);
	cvReleaseImage(&crw);
	
	return 0;
}
void point(int mouseevent, int x, int y, int flags, void* param) 
{ 
	if (mouseevent == CV_EVENT_LBUTTONDOWN) //按下左键 
	{ 
		mouse_x = x; mouse_y = y; //记录当前位置
	};
};
void getPoint(const char* win) 
{ 
	cvSetMouseCallback(win, point); //设置回调函数 
	cvWaitKey(); //等待按任意键结束程序 
};
void get_four_points(int *pointset,IplImage* crw)
{
	cout<<"Begin to get points...\n"
		<<"[Click and press any key to confirm]\n\n"
		<<"Get point 0:"<<endl;
	getPoint(WIN1);
	pointset[0] = mouse_x;pointset[1] = mouse_y;
	cout<<"x0 = "<<mouse_x<<", y0 = "<<mouse_y
		<<"\nGet point 1:\n";
	getPoint(WIN1);
	pointset[2] = mouse_x;pointset[3] = mouse_y;
	cout<<"x1 = "<<mouse_x<<", y1 = "<<mouse_y
		<<"\nGet point 2:\n";
	getPoint(WIN1);
	pointset[4] = mouse_x;pointset[5] = mouse_y;
	cout<<"x2 = "<<mouse_x<<", y2 = "<<mouse_y
		<<"\nGet point 3:\n";
	getPoint(WIN1);
	pointset[6] = mouse_x;pointset[7] = mouse_y;
	cout<<"x3 = "<<mouse_x<<", y3 = "<<mouse_y;
};
void PerspectiveTrans(IplImage* src, IplImage* dst,int* pointset ,CvMat *transmat)
{	
	//CvMat* transmat = cvCreateMat(3, 3, CV_32FC1); 
	CvPoint2D32f originpoints[4]; 
	CvPoint2D32f newpoints[4]; 
	originpoints[0]=cvPoint2D32f(pointset[0],pointset[1]);
	newpoints[0]=cvPoint2D32f(0,0);
	originpoints[1]=cvPoint2D32f(pointset[2],pointset[3]);
	newpoints[1]=cvPoint2D32f(WIDTH,0);
	originpoints[2]=cvPoint2D32f(pointset[4],pointset[5]);
	newpoints[2]=cvPoint2D32f(0,HEIGHT);
	originpoints[3]=cvPoint2D32f(pointset[6],pointset[7]);
	newpoints[3]=cvPoint2D32f(WIDTH,HEIGHT);
	cvGetPerspectiveTransform(originpoints, newpoints, transmat);
	cvWarpPerspective(src, dst, transmat); 
	
};
void invert_to_binary(IplImage* img)
{
    int height,width,step,channls;
    uchar* data;
    int i,j,k;
    //获取图片信息
    height = img->height;
    width = img->width;
    step = img->widthStep;
    channls = img->nChannels;
    data = (uchar*)img->imageData;
    for (i=0;i<height;i++)
    {
        for (j=0;j<width;j++)
        {
            for (k=0;k<channls;k++)
            {
                data[i*step+j*channls+k] = 255 - data[i*step+j*channls+k];
            }} }
};

首先通过提取图像上的四个点,然后以此进行透视变换。


然后将透视后的图片进行二值化处理,得到了可以继续细化的路线。


这是科创2B的第一部分的一小半,后面还会更新。



感谢自己又坚持了一天。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值