opencv(一):图像规整
来源:互联网 发布:中国软件国际百度 编辑:程序博客网 时间:2024/05/29 16:47
前言
在使用caffe训练好的模型测试手写字符图片的时候,发现测试集图片和训练集图片在样式上不太一致,导致测试准确率很低。所以在测试之前需要对图片预处理使其规整。
基本思路
读入一幅图片-》将其转换为灰度图-》将其进行自适应二值化-》将图片进行黑白反转,以保持与训练集一致-》查找图片中的最大连通域-》在原图上框出最大连通域的外接矩形-》取出感兴趣的字符区域-》采用三种方式将取出的字符区域图片变换成原来的大小。
代码实现
运行环境:vs2010+opencv2.4.10
采用的主要函数汇总:
cvtColor();颜色空间转换;
adaptiveThreshold();自适应二值化
findContours();提取轮廓
contourArea();计算轮廓面积
boundingRect();计算轮廓的垂直边界最小矩形
rectangle();画矩形
resize();图像缩放
具体代码如下:
#include<iostream>#include<opencv2/opencv.hpp>#include<opencv2/core/core.hpp>#include<opencv2/highgui/highgui.hpp>using namespace cv;int main(){ Mat img=imread("1.png"); //判断图片是否正确读入 if(img.empty()) { std::cout<<"read error!"<<std::endl; return -1; } namedWindow("原图"); imshow("原图", img); //将彩色图转换成灰度图 Mat sample; cvtColor(img, sample, COLOR_BGR2GRAY); //将图片进行自适应二值化 int threshold_type=CV_THRESH_BINARY; int adaptive_method=CV_ADAPTIVE_THRESH_GAUSSIAN_C; int blocksize=31; double offset=15; Mat sample_erzhi; adaptiveThreshold(sample, sample_erzhi, 255, adaptive_method, threshold_type, blocksize, offset); //将图片进行黑白反转 for(int i=0; i<100; i++) { for(int j=0; j<100; j++) { sample_erzhi.at<uchar>(i,j)=255-sample_erzhi.at<uchar)(i,j); } } namedWindow("二值反转"); imshow("二值反转", sample_erzhi); //查找连通域,计算面积,并保留最大面积 vector<vector<Point>> storage; vector<Point> contmax; vector<Vec4i> hierarchy; Mat sample_tmp=sample_erzhi.clone(); Mat sample_rect; sample_erzhi,copyTo(sample_rect); findContours(sample_erzhi, storage, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); double maxArea=0.0; Rect rect(0,0,0,0); for(int i=0; i<storage.size(); i++) { double area=fabs(contoursArea(storage[i])); if(area>maxArea) { maxArea=area; contmax=storage[i]; rect=boundingRect(contmax); } } //在二值反转后的图上画出最大连通域的外接方框 cvtColor(sample_rect, sample_rect, CV_GRAY2BGR); rectangle(sample_rect, Point(rect.x, rect.y), Point(rect.x+rect.width, rect.y+rect.height), Scalar(0,0,255), 1,8,0); namedWindow("框图"); imshow("框图", sample_rect); //取出感兴趣的字符区域 Mat sample_roi; sample_roi=sample_tmp(Rect(rect.x, rect.y, rect.width, rect.height)); //方法一填充成原图大小 Mat roi1=sample_roi.clone(); int rewidth1=((float)60/rect.height)*rect.width; resize(roi1, roi1, Size(rewidth1, 60)); Mat dst1=Mat::zeros(100,100, sample_roi.type()); for(int j=0; j<60; j++) { for(int i=0; i<rewidth1; i++) { dst1.at<uchar>((100-60)/2+j, (100-rewidth1)/2+i)=roi1.at<uchar>(j,i); } } namedWindow("方法一"); imshow("方法一", dst1); //方法二填充成原图大小 Mat roi2=sample_roi.clone(); int rewidth2=((float)100/rect.height)*rect.width; resize(roi2, roi2, Size(rewidth2, 100)); Mat dst2=Mat::zeros(100,100, sample_roi.type()); if(rewidth2<=100) { for(int j=0; j<100; j++) { for(int i=0; i<rewidth2; i++) { dst2.at<uchar>(j, (100-rewidth2)/2+i)=roi2.at<uchar>(j,i); } } } else { for(int j=0; j<100; j++) { for(int i=0; i<100; i++) { dst2.at<uchar>(j,i)=roi2.at<uchar>(j, (100-rewidth2)/2+i); } } } namedWindow("方法二"); imshow("方法二", dst2); //方法三 Mat dst3=Mat::zeros(100,100, sample_roi.type()); for(int j=0; j<rect.height; j++) { for(int i=0; i<rect.widht; i++) { dst3.at<uchar>((100-rect.height)/2+j, (100-rect.width)/2+i)=roi.at<uchar>(j,i); } } nameWindow("方法三"); imshow("方法三",dst3); waitKey(50000); }
运行结果:
opencv使用过程中的一点注意事项:
1、Mat img1=imread(“1.png”);
Mat img2=img1;
这种情况下不会为img2单独分配空间,img2和img1共享内存空间,改变其中一个将间接改变另外一个。
2、img2.at(j,i);
j对应着图像的高,i对应着图像的宽。
resize(img2, img2, dx, dy);
dx对应着图像的宽, dy对应着图像的高。
阅读全文
0 0
- opencv(一):图像规整
- 图像处理-光照规整开篇
- 图像处理-光照规整-Gradientfaces
- opencv打开一幅图像
- 学习opencv(一)--图像显示
- opencv打开一幅图像(一)
- 一.使用OpenCv加载一幅图像
- 图像处理-光照规整-直方图均衡化
- 图像处理-光照规整-Gamma校正
- 图像处理-光照规整-Gamma校正
- OpenCV入门----显示一幅图像
- 图像处理(一) opencv库
- OpenCV学习(一)显示图像
- 学习OpenCV系列文章一:显示图像
- OpenCV 计算图像一维直方图
- opencv(一)图像的加载和输出
- 利用OpenCV显示一幅图像
- opencv程序一:加载显示图像
- iOS的标识符
- iOS10.3中划线失效
- swift项目在iOS8 通过init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle
- Database mount ID mismatch(ORA-16009: invalid redo transport destination )
- 将博客搬至CSDN
- opencv(一):图像规整
- java学习经验
- ODBC学习笔记—SQLGetConnectAttr
- Java NIO系列教程(十) Java NIO DatagramChannel
- 小兔的棋盘-dp
- mysql优化
- adult数据集的转换
- Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
- [Leetcode] 272. Closest Binary Search Tree Value II 解题报告