#include "stdafx.h"
#include "ImgFilters.h" #include<opencv2\opencv.hpp> #include <iostream> using namespace cv; using namespace std;ImgFilters::ImgFilters()
{ } ImgFilters::~ImgFilters() { }//图片倒转
void ImgFilters::filp() { const char* filename = "G:\\b.png"; Mat src = imread(filename); int flipCode = atoi(filename); if (src.empty()) { throw("Faild open file"); }Mat dst;
flip(src, dst, flipCode);imshow("src", src);
//显示原图像 imshow("dst", dst); //显示翻转后的图像waitKey();
}//图片倒转
void ImgFilters::myResize() { const char *filename = "G:\\b.png"; Mat src, dst; //定义图像的大小,宽度缩小80% float scaleW = 0.8; //定义图像的大小,高度缩小80% float scaleH = scaleW;//去色读取图片
src = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); if (src.empty()) { throw("Faild open file."); } int width = static_cast<float>(src.cols*scaleW); //定义想要扩大或者缩小后的宽度,src.cols为原图像的宽度,乘以80%则得到想要的大小,并强制转换成float型 int height = static_cast<float>(src.rows*scaleH); //定义想要扩大或者缩小后的高度,src.cols为原图像的高度,乘以80%则得到想要的大小,并强制转换成float型resize(src, dst, Size(width, height));
//重新定义大小的函数imshow("src", src);
imshow("dst", dst);waitKey();
}
void ImgFilters::myRotate() {
Mat src, dst; float angle = 55.5; //定义翻转的角度为55.5度 const char* filename = "G:\\b.png"; src = imread(filename, CV_LOAD_IMAGE_GRAYSCALE); if (src.empty()) { throw("Faild open file."); }cv::Point2f center = cv::Point2f(static_cast<float>(src.cols / 2),
static_cast<float>(src.rows / 2)); //定义中心点的坐标,2f的意思为float型,中心点极为X,Y即宽度与高度的二分之一 cv::Mat affineTrans = getRotationMatrix2D(center, angle, 1.0); //getRotationMatrix2D为图像旋转的函数,第一个参数center是旋转中心点,第二个参数angle为旋转角度 //第三个1.0的参数为double scale:图像缩放因子cv::warpAffine(src, dst, affineTrans, src.size(), cv::INTER_CUBIC, cv::BORDER_REPLICATE);
//仿射变换函数warpAffine //第一个参数src为输入原图像 //第二个参数dst为输出图像 //第三个参数为affineTrans转换矩阵 //第四个参数为输出图像的size大小 //第五个参数为立方差值法 //第六个参数为边界用上下行或者左右列来复制填充cv::imshow("src", src);
cv::imshow("dst", dst);cv::imwrite("G:\\RotateDst.jpg", dst);
//输出图像cv::waitKey();
}void ImgFilters::circularity()
{ Mat imageSource, image; imageSource = imread("G:\\b.png"); cvtColor(imageSource, image, CV_BGR2GRAY); //高斯滤波 GaussianBlur(image, image, Size(9, 9), 2, 2);vector<Vec3f> circles;
//霍夫圆 HoughCircles(image, circles, CV_HOUGH_GRADIENT, 1.5, image.rows / 8, 200, 100, 0, 0); cout << "circles.size():"<<circles.size() << endl; for (size_t i = 0; i < circles.size(); i++) {cout << "圆心" <<i<<":"<< circles[i][0]<<","<<cvRound(circles[i][1]) << endl;
cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); int radius = cvRound(circles[i][2]); //绘制圆心 cv::circle(imageSource, center, 3, Scalar(0, 255, 0), -1, 8, 0); //绘制圆轮廓 cv::circle(imageSource, center, radius, Scalar(155, 50, 255), 3, 8, 0); }
imshow("Point of Contours", imageSource); //向量contours内保存的所有轮廓点集
waitKey(); }void ImgFilters::imageCrop()
{ Mat image = imread("G:\\b.png"); if (image.empty()) { return; } Rect rect1(0, 0, 400, 400); Mat roi1; image(rect1).copyTo(roi1); // copy the region rect1 from the image to roi1 imshow("裁剪窗口", roi1); waitKey(0);}
//答题卡识别小例子
class RectComp //Rect排序
{ Rect rm; public: RectComp(Rect rms) { rm = rms; } bool operator< (const RectComp& ti) const { return rm.x < ti.rm.x; } Rect getRect() { return rm; }};
void ImgFilters::exmple() {
//装载图片 Mat sourceImg = imread("G:\\aaa.png"); Mat grayImg;//图片变成灰度图片
cvtColor(sourceImg, grayImg, CV_BGR2GRAY);Mat thresholdImg;
//图片二值化 threshold(grayImg, thresholdImg, 200, 255, THRESH_BINARY_INV); Mat erodeImg; //确定腐蚀和膨胀核的大小 Mat element = getStructuringElement(MORPH_RECT, Size(4, 4)); //腐蚀操作 erode(thresholdImg, erodeImg, element); //膨胀操作 Mat dilateImg; dilate(erodeImg, dilateImg, element); //确定每张答题卡的ROI区域 Mat imag_ch1; dilateImg(Rect(5, 30, 95, 60)).copyTo(imag_ch1);imshow("img1", imag_ch1);
//提取已经涂好了的选项
std::vector<std::vector<cv::Point> > chapter1; findContours(imag_ch1, chapter1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); Mat result(imag_ch1.size(), CV_8U, cv::Scalar(255)); cv::drawContours(result, chapter1, -1, cv::Scalar(0), 2); namedWindow("resultImage", 1); cv::imshow("resultImage", result);vector<RectComp>RectCompList;
for (int i = 0; i<chapter1.size(); i++) { Rect rm = cv::boundingRect(cv::Mat(chapter1[i])); cout << "长方形" << i << ":" << "面积:" << rm.area() << endl;RectComp *ti = new RectComp(rm);
RectCompList.push_back(*ti); // printf("Rect %d x = %d,y = %d \n",i,rm.x,rm.y); } sort(RectCompList.begin(), RectCompList.end()); map<int, string>listenAnswer; //判断这部分的答题卡是否都已涂上 for (int t = 0; t<RectCompList.size(); t++) { if (RectCompList.at(t).getRect().y<32) { listenAnswer[t] = "A"; } else if ((RectCompList.at(t).getRect().y>32) && (RectCompList.at(t).getRect().y<48)) { listenAnswer[t] = "B"; } else if (RectCompList.at(t).getRect().y>48) { listenAnswer[t] = "C"; } printf("sorted %d x = %d,y = %d \n", t, RectCompList.at(t).getRect().x, RectCompList.at(t).getRect().y); }for (map<int, string>::iterator it = listenAnswer.begin(); it != listenAnswer.end(); ++it)
{ cout << "num:" << it->first + 1 << "," << "answer:" << it->second << endl; }waitKey();
}