图像处理遇到的一些问题整理(OpenCV and Emgu)

OpenCV 部分

例:Mat.at<Type> 这个Type很多新手朋友都会很困惑,因为经常因为填错而触发Error.

如上表可以看到已经列出一些常用的Type,那么如何查看Mat所加载的图片的类别呢,Mat xx;xx.type() 即可得到一个int类别的值 对照上图即可知道你应该填什么类别了。

 

关于OpenCV的颜色空间 

常见的有 RGB/HSV/Lab/Ycc

例如:HSV -----

H:0-180

S:0-255

V:0-255

RGB---

R/G/B 0-255

其中RGB对于色彩识别比较常用

HSV居中,Lab/Ycc多用于抛去亮度之后的色彩识别,比如说黑白灰。

 

Mat的加载图片办法

Imread("Filename",0) 

前面参数为图片名字 可以绝对路径 或者 相对路径 

后面的参数为图片类别,0为灰度图 >=1 为彩图 也就是BGR图

此处需要知道 OpenCV中颜色的存储顺序是 B->G->R  并非 R->G->B

 

Mat的好处和常用方法

Mat 保存图片时如果路径冲突了会自动覆盖原图片

Mat ROI 

例;Mat x ;

Mat cc = x(Rect(0,0,100,100));

此处Rect(x,y,width,height) 4个参数为切割的起始点 和切割长度和高度

Mat保存图片的方法:

Imwrite("filename",Mat x)

C++中创建文件名组合的办法,利用Sprintf()函数

例如文件名:wang123.jpg

char xx[100];

Sprintf(xx,"%s%d%s","wang",123,".jpg") 即可完成 然后xx内的值也就是文件名了

 

关于代码速度的优化一些感悟。

对于已知结果的量可以考虑用静态数组存储其值,那样在使用的时候就可以直接调用内存节省下来运算事件。

能不用IF就不要用IF 尽量使用位移符号 来处理那样可以节省很多时间。

 

2019.4.4

对于不规则多边形转变成规则矩形的方式,可以将左垂直右倾斜的区块给拉直了,如下图

测试图像-->结果结果

//测试垂线+斜线组合 全部拉直 仿射变换
void TestVerAndLean(const char* imagepath)
{
	//1.加载图片
	cv::Mat src = imread(imagepath);
	cv::Mat dst;
	cvtColor(src, dst, COLOR_BGR2GRAY);
	imshow("d1", dst);
	//2.进行2部分的拟合直线 得到点集合
	Mat image(1000, 1000, CV_8UC3, Scalar::all(0));	
	cv::Vec4f line_para;
	cv::Point point0;

	//获得拟合点
	std::vector<cv::Point> points;
	for (int i = 0; i < dst.rows; i++)
	{
		for (int j = 0; j < dst.cols; j++)
		{
			if (dst.at<uchar>(i, j) == 0)
			{
				cv::Point tP = cv::Point(j, i);
				points.push_back(tP);
			}
		}
	}

	//计算最小外包 矩形
	Rect rect = boundingRect(points);	

	//得到四个角的点计算变换矩阵(目前就是2边 分别上下第一个点位置)
	Point2f src_cor[4], dst_cor[4];//原图的4角 和 目标4角
	for (int i = 0; i < dst.rows; i++)
	{
		for (int j = 0; j < dst.cols/2; j++)
		{
			if (dst.at<uchar>(i, j) == 0)
			{
				src_cor[0].x = j; src_cor[0].y = i;
			}
		}
	}
	for (int i = dst.rows-1; i >0; i--)
	{
		for (int j = 0; j < dst.cols / 2; j++)
		{
			if (dst.at<uchar>(i, j) == 0)
			{
				src_cor[1].x = j; src_cor[1].y = i;
			}
		}
	}
	for (int i = 0; i < dst.rows; i++)
	{
		for (int j = dst.cols/2; j < dst.cols; j++)
		{
			if (dst.at<uchar>(i, j) == 0)
			{
				src_cor[2].x = j; src_cor[2].y = i;
			}
		}
	}
	for (int i = dst.rows - 1; i > 0; i--)
	{
		for (int j = dst.cols/2; j < dst.cols; j++)
		{
			if (dst.at<uchar>(i, j) == 0)
			{
				src_cor[3].x = j; src_cor[3].y = i;
			}
		}
	}

	dst_cor[0] = Point2f(rect.x, rect.y);
	dst_cor[1] = Point2f(rect.x, rect.y+rect.height);
	dst_cor[2] = Point2f(rect.x+rect.width, rect.y);
	dst_cor[3] = Point2f(rect.x+rect.width, rect.y+rect.height);
	cv::Mat convertM = getPerspectiveTransform(src_cor, dst_cor);
	cv::Mat last;
	warpPerspective(src, last, convertM, src.size());

	imshow("last", last);
	waitKey();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值