#include "head.h"
void Person::showImg(Mat &img)
{
namedWindow("透明通道显示白色背景", WINDOW_NORMAL);
if (img.empty())
{
cout << "图片路径错误" << endl;
return ;
}
imshow("透明通道显示白色背景", img);
imwrite("D:/opencvSourse/openImg/保存的图片/透明通道.png", img);
}
void Person::creatMat(Mat& img)
{
//creatOne
Mat colorImg = Mat(255, 255, CV_8UC3);
imshow("1", colorImg);
//creatTow
Mat cImg = Mat(Size(img.size()), img.type());
imshow("2", colorImg);
//深拷贝
Mat img1 = img.clone();
imshow("深拷贝1", img1);
Mat img2;
img.copyTo(img2);
imshow("深拷贝2", img2);
}
void Person::ergodic(Mat& img)
{
imshow("原始", img);
int dis = img.channels();
for (int row = 0; row < img.rows; row++)
{
for (int col = 0; col < img.cols; col++)
{
if (dis == 1)
{
img.at<uchar>(row, col) = 255 - img.at<uchar>(row, col);
}
if (dis == 3)
{
Vec3b vec = img.at<Vec3b>(row, col);
img.at<Vec3b>(row, col)[0] = 255 - vec[0];
img.at<Vec3b>(row, col)[1] = 255 - vec[1];
img.at<Vec3b>(row, col)[2] = 255 - vec[2];
}
}
}
imshow("转换", img);
}
void Person::homeErgodic(Mat& img)
{
imshow("原始", img);
int dis = img.channels();
for (int row = 0; row < img.rows; row++)
{
uchar* p = img.ptr<uchar>(row);
if (dis == 1)
{
for (int col = 0; col < img.cols; col++)
{
*p = 255 - *p;
}
}
for (int col = 0; col < img.cols; col++)
{
*p++ = 255 - *p;
*p++ = 255 - *p;
*p++ = 255 - *p;
}
}
imshow("转换", img);
}
void Person::arithmetic()
{
Mat img1 = imread("D:/opencvDownLoad/opencv-4.5.1/opencv/sources/samples/data/WindowsLogo.jpg");
Mat img2 = imread("D:/opencvDownLoad/opencv-4.5.1/opencv/sources/samples/data/LinuxLogo.jpg");
Mat dst;
add(img1, img2, dst);
imshow("add", dst);
subtract(img1, img2, dst);
imshow("subtract", dst);
multiply(img1, img2, dst);
imshow("multiply", dst);
divide(img1, img2, dst);
imshow("divide", dst);
}
void trackbarFn(int min, void *img)
{
Mat newImg = *(Mat*)img;
Mat src = Mat::zeros(newImg.size(), newImg.type());
Mat dst;
addWeighted(newImg, 1.0, src, 0, min, dst);
imshow("调节", dst);
}
void trackbarFn1(int min, void* img)
{
Mat newImg = *(Mat*)img;
Mat src = Mat::zeros(newImg.size(), newImg.type());
Mat dst;
double newMin = min / 100.0;
addWeighted(newImg, newMin, src, 0, 1, dst);
imshow("调节", dst);
}
void Person::myTrackBar(Mat &img)
{
namedWindow("调节");
imshow("调节", img);
string barName = "亮度调节";
string barName1 = "对比度调节";
string windName = "调节";
int min = 20;
int max = 200;
createTrackbar(barName, windName, &min, max, trackbarFn, (void*)&img);
createTrackbar(barName1, windName, &min, max, trackbarFn1, (void*)&img);
}
void Person::logic(Mat &img)
{
imshow("原图", img);
Mat mask = Mat::zeros(img.size(), CV_8UC1);
Mat dst;
double width = img.rows;
double height = img.cols;
for (int cols = 100; cols < height / 2; cols++)
{
uchar*p = mask.ptr<uchar>(cols);
for (int rows = 200; rows < width / 2; rows++)
{
*p++ = 255;
}
}
imshow("mask", mask);
bitwise_not(img, dst, mask);
imshow("取反", dst);
}
void Person::varianceAverage(Mat& img)
{
Mat newImg = Mat::zeros(Size(255, 255), CV_8UC3);
newImg = Scalar(0, 0, 255);
vector<Mat> vec;
split(newImg, vec);
double min; double max; Point minloc; Point maxloc;
for (int channels = 0; channels < vec.size(); channels++)
{
minMaxLoc(vec[channels], &min, &max, &minloc, &maxloc);
cout << "最小值: " << min << "\t" << "最大值: " << max << "\t"
<< "最小值x: " << minloc.x << "\t" << "最小值y: " << minloc.y << endl;
}
Mat mean; Mat stdDev;
for (int channels = 0; channels < vec.size(); channels++)
{
meanStdDev(vec[channels], mean, stdDev);
cout << "通道: " << channels << " 均值: " << mean << "\t"
<< "方差: " << stdDev << endl;
}
}
void Person::draw()
{
Mat canvas = Mat::zeros(Size(500, 500), CV_8UC3);
line(canvas, Point(0, 0), Point(500, 500), Scalar(150, 120, 180), 2, LINE_AA);
rectangle(canvas, Rect(10, 200, 300, 300), Scalar(0, 0, 200), -1, 8);
circle(canvas, Point(250, 250), 100, Scalar(200, 10, 10), -1, 8);
ellipse(canvas, RotatedRect(Point(300, 100), Size(200, 100), 45.5), Scalar(0, 200, 10), -1, LINE_AA);
imshow("convas", canvas);
Mat rngImg = Mat::zeros(Size(500, 500), CV_8UC3);
RNG rng(12345);
while (true)
{
int x = rng.uniform(0, 500); int y = rng.uniform(0, 500);
int x1 = rng.uniform(0, 500); int y1 = rng.uniform(0, 500);
line(rngImg, Point(x, y), Point(x1, y1), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);
imshow("rng", rngImg);
int key = waitKey(100);
rngImg = Scalar(0, 0, 0);
if (key == 27)
{
break;
}
}
}
void Person::splitMerge(Mat& img)
{
imshow("原图", img);
vector<Mat> vec;
split(img, vec);
vec[0] = 0;
Mat dst;
merge(vec, dst);
imshow("dst", dst);
cout << img.cols << "高" << img.rows;
Rect roi = Rect(100, 50, 300, 300);
//浅拷贝ROI
Mat roiImg = img(roi);
//深拷贝ROI
//Mat roiImg = img(roi).clone();
imshow("ROI", roiImg);
imshow("浅拷贝", img);
}
//直方图
//void Person::histogram(Mat& img)
//{
// imshow("原图", img);
// vector<Mat> vec;
// split(img, vec);
// Mat bImg; Mat gImg; Mat rImg;
// //竖条个数
// int bins = 256;
// //范围
// float rangs[] = {0,255};
// //多个通道rangs
// const float* rangsChannels = { rangs };
// //直方图
// calcHist(&vec[0], 1, 0, Mat(), bImg, 1, &bins, &rangsChannels, true, false);
// calcHist(&vec[1], 1, 0, Mat(), gImg, 1, &bins, &rangsChannels, true, false);
// calcHist(&vec[2], 1, 0, Mat(), rImg, 1, &bins, &rangsChannels, true, false);
//
// //归一化
// Mat dst = Mat::zeros(Size(600, 500), CV_8UC3);
// int margin = 50;
// int dH = dst.rows - 2 * margin;
// normalize(bImg, bImg, 0, dH, NORM_MINMAX, -1, Mat());
// normalize(gImg, gImg, 0, dH, NORM_MINMAX, -1, Mat());
// normalize(rImg, rImg, 0, dH, NORM_MINMAX, -1, Mat());
//
// //把直方图放到归一化的img
//
// //求bins
// float xStep = (dst.cols - 2 * margin) / 256.0;
// cout << xStep << endl;
// //i最大值为256, 但是后面i++, so: i = 255
// for (int i = 0; i < 255; i++)
// {
// //求dims
// //float dims = bImg.at<float>(i, 0);
// //line p1
// /* Point p1 = Point(xStep * i, margin+(dst.rows - dims) );
// dims = dst.at<float>(i+1, 0);
// Point p2 = Point(xStep * i, margin + (dst.rows - dims) );*/
//
//
// //line(dst, p1, p2,Scalar(255,0,0),2,8);
// line(dst, Point(xStep * i + margin, margin + (dH - bImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - bImg.at<float>(i + 1, 0))), Scalar(255, 0, 0),2,8,0);
// line(dst, Point(xStep * i + margin, margin + (dH - gImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - gImg.at<float>(i + 1, 0))), Scalar(0, 255, 0),2,8,0);
// line(dst, Point(xStep * i + margin, margin + (dH - rImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - rImg.at<float>(i + 1, 0))), Scalar(0, 0, 255),2,8,0);
// }
// imshow("直方图", dst);
//}
void Person::histogram(Mat& img)
{
imshow("原始", img);
int bins = 256;
float rangs[] = { 0,255 };
const float* everyRangs = { rangs };
vector<Mat> vec;
split(img, vec);
Mat bImg; Mat gImg; Mat rImg;
calcHist(&vec[0], 1, 0, Mat(), bImg, 1, &bins, &everyRangs, true, false);
calcHist(&vec[1], 1, 0, Mat(), gImg, 1, &bins, &everyRangs, true, false);
calcHist(&vec[2], 1, 0, Mat(), rImg, 1, &bins, &everyRangs, true, false);
Mat dst = Mat::zeros(Size(600, 400), img.type());
float margin = 50;
float height = dst.rows - 2 * 50;
float xStep = (dst.cols - 2 * margin) / float(bins);
cout << "步长" << xStep << endl;
cout << "高度" << height << endl;
normalize(bImg, bImg, 0, height, NORM_MINMAX, -1, Mat());
normalize(gImg, gImg, 0, height, NORM_MINMAX, -1, Mat());
normalize(rImg, rImg, 0, height, NORM_MINMAX, -1, Mat());
for (int i = 0; i < bins-1; i++)
{
line(dst, Point(i * xStep + margin, margin + (height - bImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - bImg.at<float>((i + 1) , 0))), Scalar(255, 0, 0), 2, 8, 0);
line(dst, Point(i * xStep + margin, margin + (height - gImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - gImg.at<float>((i + 1) , 0))), Scalar(0, 255, 0), 2, 8, 0);
line(dst, Point(i * xStep + margin, margin + (height - rImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - rImg.at<float>((i + 1) , 0))), Scalar(0, 0, 255), 2, 8, 0);
}
imshow("归一化", dst);
}
//直方图均衡化
void Person::myEqualizeHist(Mat& img)
{
cvtColor(img, img, COLOR_BGR2GRAY);
imshow("灰色", img);
Mat equImg;
equalizeHist(img, equImg);
Mat src; Mat dst;
int bins = 256;
float rang[] = { 0,255 };
const float* rangs = { rang };
calcHist(&img, 1, 0, Mat(), src, 1, &bins, &rangs, true, false);
calcHist(&equImg, 1, 0, Mat(), dst, 1, &bins, &rangs, true, false);
Mat outImg = Mat::zeros(Size(600, 400), CV_8UC3);
int margin = 50;
float Hight = float(outImg.rows) - float(2 * margin);
float step = (outImg.cols - 2 * margin) / float(bins);
cout << Hight << "\t" << step << endl;
normalize(src, src, 0, Hight, NORM_MINMAX, -1, Mat());
normalize(dst, dst, 0, Hight, NORM_MINMAX, -1, Mat());
for (int i = 0; i < bins - 1; i++)
{
line(outImg, Point(step * i + margin, margin + (Hight - src.at<float>(i, 0))), Point(step * (i + 1) + margin, margin + (Hight - src.at<float>(i + 1, 0))), Scalar(0, 0, 255), 2, 8, 0);
line(outImg, Point(step * i + margin, margin + (Hight - dst.at<float>(i, 0))), Point(step * (i + 1) + margin, margin + (Hight - dst.at<float>(i + 1, 0))), Scalar(0, 255, 255), 2, 8, 0);
}
imshow("结果", outImg);
}
//直方图比较
void Person::histCompare(Mat& img, Mat& img1)
{
Mat dst; Mat dst1;
int bins[] = { 200,200,200 };
float rang[] = { 0,255 };
const float* rangs[] = { rang,rang,rang };
int channls[] = { 0,1,2 };
calcHist(&img, 1, channls, Mat(), dst, img.channels(), bins, rangs, true, false);
calcHist(&img1, 1, channls, Mat(), dst1, img.channels(), bins, rangs, true, false);
normalize(dst, dst, 0, 1, NORM_MINMAX, -1, Mat());
normalize(dst1, dst1, 0, 1, NORM_MINMAX, -1, Mat());
float result1 = compareHist(dst, dst1, HISTCMP_BHATTACHARYYA); // 越大越不像
float resemble = compareHist(dst, dst, HISTCMP_BHATTACHARYYA);
cout << "巴氏距离" << result1 << "\t" << resemble << endl;
float result2 = compareHist(dst, dst1, HISTCMP_CORREL);
float resemble1 = compareHist(dst, dst, HISTCMP_CORREL);
cout << "相似性" << result2 << "\t" << resemble1 << endl;
}
void Person::colormap(Mat& img)
{
imshow("原始", img);
Mat dst;
applyColorMap(img, dst, COLORMAP_AUTUMN);
imshow("颜色表", dst);
}
void Person::myblur(Mat& img)
{
imshow("img", img);
float width = img.cols;
float height = img.rows;
Mat dst = img.clone(); Mat dst1 = img.clone();
float b_value; float g_value; float r_value;
for (int h = 1; h < height - 1; h++)
{
for (int w = 1; w < width - 1; w++)
{
dst.at<Vec3b>(h, w)[0] = (img.at<Vec3b>(h - 1, w - 1)[0] + img.at<Vec3b>(h - 1, w)[0] + img.at<Vec3b>(h - 1, w + 1)[0] +
img.at<Vec3b>(h, w - 1)[0] + img.at<Vec3b>(h, w)[0] + img.at<Vec3b>(h, w + 1)[0] +
img.at<Vec3b>(h + 1, w - 1)[0] + img.at<Vec3b>(h + 1, w)[0] + img.at<Vec3b>(h + 1, w + 1)[0])
/ 9;
dst.at<Vec3b>(h, w)[1] = (img.at<Vec3b>(h - 1, w - 1)[1] + img.at<Vec3b>(h - 1, w)[1] + img.at<Vec3b>(h - 1, w + 1)[1] +
img.at<Vec3b>(h, w - 1)[1] + img.at<Vec3b>(h, w)[1] + img.at<Vec3b>(h, w + 1)[1] +
img.at<Vec3b>(h + 1, w - 1)[1] + img.at<Vec3b>(h + 1, w)[1] + img.at<Vec3b>(h + 1, w + 1)[1]) / 9;
dst.at<Vec3b>(h, w)[2] = (img.at<Vec3b>(h - 1, w - 1)[2] + img.at<Vec3b>(h - 1, w)[2] + img.at<Vec3b>(h - 1, w + 1)[2] +
img.at<Vec3b>(h, w - 1)[2] + img.at<Vec3b>(h, w)[2] + img.at<Vec3b>(h, w + 1)[2] +
img.at<Vec3b>(h + 1, w - 1)[2] + img.at<Vec3b>(h + 1, w)[2] + img.at<Vec3b>(h + 1, w + 1)[2]) / 9;
}
}
imshow("myBlur", dst);
blur(img, dst1, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
imshow("API", dst1);
}
void Person::borderBlur(Mat& img)
{
imshow("ipt", img);
Mat dst;
float margin = 9;
//copyMakeBorder(img, dst, margin, margin, margin, margin, BORDER_DEFAULT);
copyMakeBorder(img, dst, margin, margin, margin, margin, BORDER_CONSTANT,Scalar(0,0,200));
imshow("卷积", dst);
}
void Person::GauBox(Mat& img)
{
imshow("ipt", img);
Mat dst; Mat dst1;
boxFilter(img, dst, -1, Size(5, 5), Point(-2, -2), true, BORDER_DEFAULT);
GaussianBlur(img, dst1, Size(5, 5), BORDER_DEFAULT);
imshow("高斯模糊", dst1);
imshow("盒子模糊", dst);
}
void Person::customFilter(Mat& img)
{
imshow("原图", img);
//自定义均值卷积
Mat dst;
int width = 15;
int height = 15;
//归一化
Mat kernel = Mat::ones(width, height, CV_32F) / float(width * height);
filter2D(img, dst, -1, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
imshow("自定义均值滤波", dst);
//自定义高斯卷积
Mat dst1;
int gWidth = 2;
int gHeight = 2;
/*Mat kernel1 = (Mat_<int>(gWidth, gHeight) << 1, 0, 0, 0, 1, 0, 0, 0, -1);*/
Mat kernel1 = (Mat_<int>(gWidth, gHeight) << 1, 0, 0,-1);
filter2D(img, dst1, CV_32F, kernel1, Point(-1, -1), 200, BORDER_DEFAULT);
convertScaleAbs(dst1, dst1);
imshow("非均值滤波", dst1);
}
void Person::myRobot(Mat& img)
{
//robot
imshow("原图", img);
Mat xKernel = (Mat_<int>(2, 2) << 1, 0, 0, -1);
Mat yKernel = (Mat_<int>(2, 2) << 0, 1, -1, 0);
Mat xImg; Mat yImg; Mat dst; Mat dst1; Mat dst2;
filter2D(img, xImg, CV_32F, xKernel, Point(-1, -1), 0, BORDER_DEFAULT);
filter2D(img, yImg, CV_32F, yKernel, Point(-1, -1), 0, BORDER_DEFAULT);
convertScaleAbs(xImg, xImg);
convertScaleAbs(yImg, yImg);
dst = xImg + yImg;
imshow("robot", dst);
//sobel
Sobel(img, xImg, CV_32F, 1, 0);
Sobel(img, yImg, CV_32F, 1, 0);
convertScaleAbs(xImg, xImg);
convertScaleAbs(yImg, yImg);
addWeighted(xImg, 0.5, yImg, 0.5, 0, dst1);
imshow("sobel", dst1);
//scharr
Scharr(img, xImg, CV_32F, 1, 0);
Scharr(img, yImg, CV_32F, 1, 0);
convertScaleAbs(xImg, xImg);
convertScaleAbs(yImg, yImg);
addWeighted(xImg, 0.5, yImg, 0.5, 0, dst1);
imshow("scharr", dst1);
}
void Person::myLaplacian(Mat& img)
{
imshow("原图", img);
Mat dst; Mat dst1;
Laplacian(img, dst, -1, 3, 1, 123, BORDER_DEFAULT);
imshow("拉普拉斯", dst);
//图像锐化 = 拉普拉斯+img本身
Mat kernel = (Mat_<int>(3,3)<<0, -1, 0,
-1, 5, -1,
0, -1, 0);
filter2D(img, dst1, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
convertScaleAbs(dst1, dst1);
imshow("锐化", dst1);
}
void Person::sum(Mat& img)
{
//blur - lapla
imshow("原图", img);
Mat gaussImg; Mat laplaImg; Mat sumImg;
GaussianBlur(img, gaussImg, Size(3, 3), 0);
Laplacian(img, laplaImg, -1, 3,1.0,0,BORDER_DEFAULT);
addWeighted(gaussImg, 1.0, laplaImg, -0.7, 0, sumImg);
imshow("sum锐化", sumImg);
}
void Person::noise(Mat& img)
{
imshow("原图", img);
//椒盐噪声
Mat saltPepper = img.clone();
RNG rng(123456);
int width = img.cols;
int height = img.rows;
int number = 10000;
for (int i = 0; i < number; i++) {
int x = rng.uniform(0, width);
int y = rng.uniform(0, height);
if (i % 2)
{
saltPepper.at<Vec3b>(x, y) = Vec3b(255, 255, 255) ;
}
else
{
saltPepper.at<Vec3b>(x, y) = Vec3b(0, 0, 0) ;
}
}
imshow("椒盐噪声", saltPepper);
//高斯噪声
Mat dst;
Mat randnImg = Mat::zeros(img.size(), img.type());
randn(randnImg, Scalar(20, 30, 40), Scalar(10, 15, 20));
imshow("高斯原图", randnImg);
add(img, randnImg, dst);
imshow("高斯噪声", dst);
Mat dst1; Mat dst2; Mat dst3;
//利用中值去除椒盐噪声
medianBlur(saltPepper, dst1, 3);
imshow("中值去噪", dst1);
//均值去噪
GaussianBlur(dst, dst2, Size(3, 3), 0);
medianBlur(dst, dst3, 3);
imshow("高斯去噪", dst2);
imshow("中值去噪高斯", dst3);
}
void Person::cleanNoise(Mat& img)
{
Mat dst; Mat dst1;
imshow("原图", img);
//双边模糊去噪
bilateralFilter(img, dst, 10, 100, 10);
imshow("高斯去噪", dst);
//非局部均值滤波
fastNlMeansDenoising(img, dst1, 10, 7, 21);
imshow("非局部均值去噪", dst1);
}
void myCanny(int min, void* img)
{
Mat newImg = *(Mat*)img;
Mat dst; Mat dst1;
Canny(newImg, dst, min, 200, 3, false);
bitwise_and(newImg, newImg, dst1, dst);
imshow("边缘提取", dst1);
}
void Person::canny(Mat& img)
{
string barName = "提取范围";
string winName = "边缘提取";
namedWindow(winName, WINDOW_AUTOSIZE);
imshow("原图", img);
int min = 50;
int max = 220;
createTrackbar(barName, winName, &min, max, myCanny,(void*)&img);
myCanny(0, (void*)&img);
}
//二值化分割
void Person::myThreshold(Mat& img)
{
Mat dst;
cvtColor(img, img, COLOR_BGR2GRAY);
imshow("原图灰色图像", img);
//二值化
threshold(img, dst, 127, 255, THRESH_BINARY);
imshow("二值化", dst);
//反二值化
threshold(img, dst, 127, 255, THRESH_BINARY_INV);
imshow("反二值化", dst);
//阈值化切割, 小于阈值化保持原数据, 否则为T
threshold(img, dst, 127, 255, THRESH_TRUNC);
imshow("阈值化切割", dst);
//阈值化,大于T的保持原数据, 其他的为0
threshold(img, dst, 127, 255, THRESH_TOZERO);
imshow("阈值化", dst);
//反阈值化,
threshold(img, dst, 127, 255, THRESH_TOZERO_INV);
imshow("反阈值化", dst);
}
//返回二值化分割
Mat Person::myThresh(const Mat& img)
{
Mat newImg = img.clone();
GaussianBlur(newImg, newImg, Size(3, 3), 0);
cvtColor(newImg, newImg, COLOR_BGR2GRAY);
Mat dst;
threshold(newImg, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
return dst;
}
//全局求阈值分割
void Person::tThreshold(Mat& img)
{
Mat dst;
cvtColor(img, img, COLOR_BGR2GRAY);
imshow("原图", img);
Scalar m = mean(img);
threshold(img, dst, m[0], 255, THRESH_BINARY);
imshow("均值", dst);
//otsu
double otsu = threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("otsu", dst);
//三角法
double angle = threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
imshow("三角法", dst);
cout << "otsu切割阈值T: " << otsu << "\t" << "三角法: " << angle << endl
<<"\t" << "均值:"<<m[0];
}
//自适应阈值分割
void Person::myAdaptive(Mat &img)
{
Mat dst;
cvtColor(img, img, COLOR_BGR2GRAY);
imshow("原图", img);
threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("otsu", dst);
//自适应
adaptiveThreshold(img, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 21, 5);
imshow("自适应", dst);
}
//联通组件
void Person::connectComp(Mat& img)
{
RNG rn(12345);
imshow("原图", img);
Mat denoi;
GaussianBlur(img, denoi, Size(11, 11), 0);
imshow("去噪", denoi);
Mat grey;
cvtColor(denoi, grey, COLOR_BGR2GRAY);
Mat cutting;
threshold(grey, cutting, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("二值化", cutting);
Mat labels = Mat::zeros(img.size(), CV_32S);
int num = connectedComponents(cutting, labels, 8, CV_32S, CCL_DEFAULT);
cout << "数量" << num << endl;
//染色
vector<Vec3b>color(num);
color[0] = Vec3b(0, 0, 0);
for (int index = 1; index < num; index++)
{
color[index] = Vec3b(rn.uniform(0, 256), rn.uniform(0, 256), rn.uniform(0, 256));
}
Mat result = Mat::zeros(img.size(), CV_8UC3);
for (int x = 0; x < result.rows; x++)
{
for (int y = 0; y < result.cols; y++)
{
result.at<Vec3b>(x, y) = color[labels.at<int>(x, y)];
}
}
//显示详细信息
Mat stats; Mat centroids;
int num1 = connectedComponentsWithStats(cutting, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
string numn = to_string(num1);
for (int i = 1; i < num1; i++)
{
//center
double centerX = centroids.at<double>(i, 0);
double centerY = centroids.at<double>(i, 1);
//ractangle
int racLeft = stats.at<int>(i, CC_STAT_LEFT);
int racTop = stats.at<int>(i, CC_STAT_TOP);
int racWidth = stats.at<int>(i, CC_STAT_WIDTH);
int racHeight = stats.at<int>(i, CC_STAT_HEIGHT);
int area = stats.at<int>(i, CC_STAT_AREA);
cout << "面积" << i << area << endl;
string s = to_string(area);
circle(result, Point(centerX, centerY), 3, Scalar(255, 20, 20), 2, 8);
Rect rect = Rect(racLeft, racTop, racWidth, racHeight);
rectangle(result, rect, Scalar(0, 0, 200), 2, LINE_8);
putText(result, s, Point(centerX, centerY), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 2, 8);
putText(result, numn, Point(50,50), FONT_HERSHEY_PLAIN, 3, Scalar(0, 255, 0), 2, 8);
}
imshow("切割染色", result);
}
//void Person::connectComp(Mat& img)
//{
// RNG rng(12345);
// imshow("ipt", img);
// GaussianBlur(img, img, Size(3, 3), 0);
// Mat gray; Mat binary;
// cvtColor(img, gray, COLOR_BGR2GRAY);
// threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
// imshow("二值化", binary);
// Mat lables = Mat::zeros(binary.size(), CV_32S);
// int num = connectedComponents(binary, lables, 8, CV_32S, CCL_DEFAULT);
// vector<Vec3b>vec(num);
// vec[0] = Vec3b(0, 0, 0);
// for (int i = 0; i < num; i++)
// {
// vec[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
// }
// Mat result = Mat::zeros(img.size(), img.type());
// for (int x = 0; x < result.rows; x++)
// {
// for (int y = 0; y < result.cols; y++)
// {
// int lab = lables.at<int>(x, y);
// result.at<Vec3b>(x, y) = vec[lab];
// }
// }
// imshow("颜色表", result);
//}
//轮廓提取
void Person::myContour(Mat& img)
{
Mat binaryImg = this->myThresh(img).clone();
Mat dst = Mat::zeros(img.size(),CV_8UC3);
Mat dst1 = dst.clone();
Mat dst2 = dst.clone();
imshow("二值化", binaryImg);
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(binaryImg, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
for (int i = 0; i < contours.size(); i++)
{
drawContours(dst, contours, i, Scalar(0, 255, 0), 2, LINE_8);
}
imshow("轮廓", dst);
findContours(binaryImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
drawContours(dst1, contours, -1, Scalar(255, 0, 0), 2, 8);
imshow("最大轮廓", dst1);
}
//轮廓细节
void Person::contourDetails(Mat& img)
{
Mat result = Mat::zeros(img.size(), CV_8UC3);
imshow("原图", img);
GaussianBlur(img, img, Size(3, 3), 0);
cvtColor(img, img, COLOR_BGR2GRAY);
Mat dst;
threshold(img, dst, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("二值化分割", dst);
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
//Mat result = Mat::zeros(img.size(), CV_8UC3);
findContours(dst, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
/*double minLength;
cout << "输入最小周长" << endl;
cin >> minLength;
double minArea;
cout << "输入最小面积" << endl;
cin >> minArea;*/
for (int i = 0; i < contours.size(); i++)
{
if (arcLength(contours[i],true) < 100 || contourArea(contours[i]) < 10) continue;
//最大外接矩形
Rect maxRect = boundingRect(contours[i]);
rectangle(result, maxRect, Scalar(200, 20, 20), 2, 8);
//最小外接矩形
RotatedRect minRect = minAreaRect(contours[i]);
ellipse(result, minRect, Scalar(20, 200, 20), 2, 8);
Point2f pts[4];
//通过点连接成线绘制最小外接矩形
minRect.points(pts);
for (int i = 0; i < 4; i++)
{
line(result, pts[i], pts[(i + 1)%4], Scalar(20, 20, 200), 2, 8);
}
drawContours(result, contours, -1, Scalar(100, 100, 100), 2, 8);
cout << "轮廓" << i << "面积: " << contourArea(contours[i]) << "\t" << "轮廓" << i << "周长: " << arcLength(contours[i], true) << endl;
}
imshow("输出", result);
}
//轮廓比较
void contoursFn( Mat &dst, const vector<vector<Point>> &imgContours, const vector<vector<Point>>& srcContours)
{
Moments srcMm = moments(srcContours[0]);
Mat srcHu;
HuMoments(srcMm, srcHu);
for (int i = 0; i < imgContours.size(); i++)
{
Mat imgHu;
Moments imgMm = moments(imgContours[i]);
double pX = imgMm.m10 / imgMm.m00;
double pY = imgMm.m01 / imgMm.m00;
circle(dst, Point(pX, pY), 3, Scalar(200, 200, 20), 2, LINE_8);
HuMoments(imgMm, imgHu);
double ss = matchShapes(imgHu, srcHu, CONTOURS_MATCH_I1,0);
//cout << ss << endl;
if (ss < 2.0)
{
cout << ss << endl;
drawContours(dst, imgContours, i, Scalar(20, 20, 200), 2, 8);
}
else
{
cout << "匹配不成功" << endl;
}
}
imshow("axx", dst);
/*for (int i = 0; i < srcContours.size(); i++)
{
moImg.push_back(moments(srcContours[i]));
}*/
}
void Person::contourComp(Mat& img, Mat& src)
{
namedWindow("匹配轮廓图", WINDOW_FREERATIO);
imshow("匹配轮廓图", src);
Mat binaryImg = this->myThresh(img);
Mat binarysrc = this->myThresh(src);
vector<vector<Point>> imgContours;
vector<vector<Point>> srcContours;
vector<Vec4i> hierarchy;
vector<Vec4i> hierarchy1;
findContours(binaryImg, imgContours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
findContours(binarysrc, srcContours, hierarchy1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
contoursFn(img, imgContours, srcContours);
}
//根据轮廓拟合
void Person::contourProx(Mat& img)
{
imshow("原图", img);
Mat binaryImg = this->myThresh(img);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binaryImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
for (int i = 0; i < contours.size(); i++)
{
Mat poly;
approxPolyDP(contours[i], poly, 4, true);
cout << "图形:" << i << "行数 " << poly.rows << "列数: " << poly.cols << endl;
double len = arcLength(contours[i], true);
double Area = contourArea(contours[i]);
Moments mm = moments(contours[i]);
double pX = mm.m10 / mm.m00;
double pY = mm.m01 / mm.m00;
//if (poly.rows = 4)
//{
// putText(img, "矩形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// string Sarea = "面积: " + to_string(Area);
// string Slen = "周长: " + to_string(len);
// /*putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
// circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
//}
//if (poly.rows = 3)
//{
// putText(img, "三角形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// string Sarea = "面积: " + to_string(Area);
// string Slen = "周长: " + to_string(len);
// /*putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
// circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
//}
//if (poly.rows = 6)
//{
// putText(img, "6边形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// string Sarea = "面积: " + to_string(Area);
// string Slen = "周长: " + to_string(len);
///* putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
// circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
//}
//if (poly.rows > 12)
//{
// putText(img, "圆", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// string Sarea = "面积: " + to_string(Area);
// string Slen = "周长: " + to_string(len);
///* putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
// putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
// circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
//}
putText(img, "我", Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
}
imshow("判断轮廓图像", img);
}
void Person::myImg(Mat& img)
{
if (img.empty())
{
cout << "图片路径错误" << endl;
return ;
}
imshow("原图", img);
}
void Person::myThreshold(Mat& img)
{
Mat gray; Mat binary;
cvtColor(img, gray, COLOR_BGR2GRAY);
//通过mean求阈值T
Scalar T = mean(gray);
threshold(gray, binary, T[0], 255, THRESH_BINARY);
cout << "全局阈值T: " << T[0] << endl;
imshow("全局阈值", binary);
//通过otsu求
double otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("otsu", binary);
cout << "otsu: " << otsu << endl;
//三角法
double trian = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
imshow("trian", binary);
cout << "triangle: " << trian << endl;
}
//返回除燥的灰色图像
Mat Person::myGray(Mat& img)
{
Mat gray; Mat binary;
GaussianBlur(img, img, Size(3, 3), 0);
cvtColor(img, gray, COLOR_BGR2GRAY);
return gray;
}
//返回二值化
Mat Person::myBinary(Mat& img)
{
Mat binary;
Mat gray = this->myGray(img);
//threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
return binary;
}
void Person::adpThreshold(Mat& img)
{
Mat dst; Mat dst1;
imshow("原图", img);
Mat binary = this->myGray(img);
imshow("灰色", binary);
double T = threshold(binary, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("全局阈值", dst);
adaptiveThreshold(binary, dst1, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 23, 5);
imshow("自适应阈值", dst1);
}
//联通组件
void Person::myCopNect(Mat& img)
{
RNG rng(12345);
imshow("原图", img);
Mat binary = this->myBinary(img);
imshow("二值化", binary);
Mat labels = Mat::zeros(img.size(), CV_32S);
int num = connectedComponents(binary, labels, 8, CV_32S, CCL_DEFAULT);
cout << "组件" << num - 1 << endl;
vector<Vec3b> vec(num);
vec[0] = Vec3b(0, 0, 0);
for (int i = 1; i < vec.size(); i++)
{
vec[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
}
Mat src = Mat::zeros(img.size(), img.type());
for (int y = 0; y < img.rows; y++)
{
for (int x = 0; x < img.cols; x++)
{
int label = labels.at<int>(y, x);
src.at<Vec3b>(y, x) = vec[label];
}
}
imshow("lable", src);
}
void Person::compnect1(Mat& img)
{
imshow("原图", img);
RNG rng(12345);
Mat binary = this->myBinary(img);
Mat labels = Mat::zeros(img.size(),CV_32S);
Mat stats; Mat centroids;
int num = connectedComponentsWithStats(binary, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
Mat result = Mat::zeros(img.size(), CV_8UC3);
vector<Vec3b> color(num);
color[0] = Vec3b(0, 0, 0);
for (int i = 1; i < num; i++)
{
color[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
}
for (int row = 0; row < img.rows; row++)
{
for (int col = 0; col < img.cols; col++)
{
int lable = labels.at<int>(row, col);
result.at<Vec3b>(row, col) = color[lable];
}
}
for (int i = 1; i < num; i++)
{
double pX = centroids.at<double>(i, 0);
double pY = centroids.at<double>(i, 1);
int left = stats.at<int>(i, CC_STAT_LEFT);
int top = stats.at<int>(i, CC_STAT_TOP);
int width = stats.at<int>(i, CC_STAT_WIDTH);
int height = stats.at<int>(i, CC_STAT_HEIGHT);
string area = to_string( stats.at<int>(i, CC_STAT_AREA));
putText(result, area, Point(pX - 10, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(200, 20, 20), 2, 8);
rectangle(result,Rect(left,top,width,height),Scalar(20,20,200),2,8);
}
putText(result, to_string(num - 1), Point(50, 50), FONT_HERSHEY_PLAIN, 2, Scalar(150, 150, 150));
imshow("connect", result);
}
//轮廓发现
void Person::myContours(Mat& img)
{
Mat result = Mat::zeros(img.size(), CV_8UC3);
imshow("原图", img);
Mat binary = this->myBinary(img);
vector<vector<Point>> contours;
vector<Vec4i> hierachy;
findContours(binary, contours, hierachy, RETR_LIST,CHAIN_APPROX_SIMPLE, Point());
//drawContours(result, contours, -1, Scalar(0, 0, 200), 2, 8);
for (int i = 0; i < contours.size(); i++)
{
drawContours(result, contours, i, Scalar(0, 0, 200), 2, 8);
}
imshow("轮廓", result);
}
void Person::myContours1(Mat& img)
{
imshow("原图", img);
Mat binary = this->myBinary(img);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[i]);
double length = arcLength(contours[i], true);
if (area < 100 || length <10) continue;
drawContours(img, contours, i,Scalar(0,0,200),-1,8);
Rect box = boundingRect(contours[i]);
rectangle(img, box, Scalar(200, 0, 0), 2, 8);
ellipse(img, minAreaRect(contours[i]), Scalar(0, 200, 0), 2, 8);
Point2f poin[4];
RotatedRect roRec = minAreaRect(contours[i]);
roRec.points(poin);
for (int i = 0; i < 4; i++)
{
line(img, poin[i], poin[(i + 1) % 4], Scalar(157, 157, 157), 2, 8);
}
}
imshow("轮廓", img);
}
void Person::momentCop(Mat& img,Mat &img1)
{
imshow("模板", img);
imshow("匹配", img1);
Mat binary = this->myBinary(img);
Mat binary1 = this->myBinary(img1);
vector<vector<Point>> contours;
vector<vector<Point>> contours1;
vector<Vec4i> hierarchy;
vector<Vec4i> hierarchy1;
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
findContours(binary1, contours1, hierarchy1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
Mat src; Mat src1;
cout << contours.size() << endl;
for (int i = 0; i < contours.size(); i++)
{
Moments res = moments(contours[i]);
Moments res1 = moments(contours1[0]);
HuMoments(res, src);
HuMoments(res1, src1);
double num = matchShapes(src, src1, CONTOURS_MATCH_I1, 0);
if (num < 2)
{
drawContours(img, contours, i, Scalar(0, 0, 200), 2, 8);
}
cout << num << endl;
double pX = res.m10 / res.m00;
double pY = res.m01 / res.m00;
circle(img, Point(pX, pY), 3, Scalar(200, 0, 0), 2, 8);
}
imshow("模板", img);
}
void Person::approxP(Mat& img)
{
imshow("原图", img);
Mat binary = this->myBinary(img);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Mat src;
for (int i = 0; i < contours.size(); i++)
{
double pX = moments(contours[i]).m10 / moments(contours[i]).m00;
double pY = moments(contours[i]).m01 / moments(contours[i]).m00;
approxPolyDP(contours[i], src, 4, true);
cout << "端点数量: " << src.rows << endl;
if (src.rows == 4)
{
putText(img, "rec", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
}
if (src.rows == 3)
{
putText(img, "triangle", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
}
if (src.rows == 6)
{
putText(img, "hex", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
}
if (src.rows > 10)
{
putText(img, "ploy", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
}
}
imshow("图形判断", img);
}
//返回二值化轮廓
vector<vector<Point>> Person::contourOne(Mat& img)
{
Mat binary = this->myBinary(img);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
return contours;
}
//拟合
void Person::myFitEllipse(Mat& img)
{
imshow("原图", img);
vector<vector<Point>> contours = this->contourOne(img);
for (int i = 0; i < contours.size(); i++)
{
RotatedRect rotRect = fitEllipse(contours[i]);
Point center = rotRect.center;
string height = to_string(rotRect.size.height);
string width = to_string(rotRect.size.width);
string are = to_string(rotRect.size.area());
ellipse(img, rotRect, Scalar(255, 0, 10), 2, 8);
circle(img, center, 3, Scalar(0, 255, 0), 2, LINE_8);
}
imshow("处理图", img);
}
//霍夫直线
void Person::Houline(Mat& img)
{
imshow("原图", img);
Mat binary = this->myBinary(img);
vector<Vec3f>lines;
HoughLines(binary, lines, 1, CV_PI / 180, 160, 0, 0);
Point p1; Point p2;
for (int i = 0; i < lines.size(); i++)
{
double step = lines[i][0];
double angle = lines[i][1];
double add = lines[i][2];
cout << "直线" << i << "\t" << "距离: " << step << "角度: " << angle << i << "累加点: " << add << endl;
double x = cos(angle);
double y = sin(angle);
double x0 = step * x;
double y0 = step * y;
p1.x = cvRound(x0 + 500 * -y);
p1.y = cvRound(y0 + 500 * x);
p2.x = cvRound(x0 - 500 * -y);
p2.y = cvRound(y0 - 500 * x);
line(img, p1, p2, Scalar(0, 0, 255), 2, 8);
}
imshow("霍夫直线", img);
}
//霍夫线段
void Person::houlineP(Mat& img)
{
Mat result = Mat::zeros(img.size(), img.type());
imshow("原图", img);
Mat binary = this->myBinary(img);
vector<Vec4i> lines;
imshow("binary",binary);
HoughLinesP(binary, lines, 1, CV_PI / 180, 80,30,10);
//Point p1; Point p2;
for (int i = 0; i < lines.size(); i++)
{
/*p1.x = lines[i][0];
p1.y = lines[i][1];
p2.x = lines[i][2];
p2.y = lines[i][3];*/
//line(result, p1, p2, Scalar(0, 0, 255), 1, 8);
line(result, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(255, 0, 0), 1, 8);
}
imshow("霍夫直线", result);
}
//霍夫圆检测
void Person::houghCir(Mat &img)
{
imshow("原图", img);
Mat result = Mat::zeros(img.size(), CV_8UC3);
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray, Size(15,15), 2, 2);
vector<Vec3f> cir;
int dp = 2;
double cirSpace = 5;
int add = 100;
int maxThreshold = 100;
double cirMin = 15; double cirMax = 100;
HoughCircles(gray, cir, HOUGH_GRADIENT, dp, cirSpace, add, maxThreshold, cirMin, cirMax);
for (int i = 0; i < cir.size(); i++)
{
int cenX = round(cir[i][0]);
int cenY = round(cir[i][1]);
int radius = round(cir[i][2]);
circle(result, Point(cenX, cenY), radius, Scalar(0, 0, 200), 2, 8);
}
imshow("霍夫找园", result);
}
void Person::erodeDilate(Mat& img)
{
imshow("原图", img);
Mat result;
Mat result1;
Mat binary = this->myBinary(img);
Mat rect = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
erode(img, result1, rect);
imshow("腐蚀", result1);
dilate(img, result, rect);
imshow("膨胀", result);
}
//开闭操作
void Person::openCloss(Mat& img)
{
Mat dst;
imshow("原图", img);
Mat binary = this->myBinary(img);
imshow("二值化", binary);
Mat kernel = getStructuringElement(MORPH_RECT, Size(15, 1), Point(-1, -1));
morphologyEx(binary, dst, MORPH_OPEN, kernel, Point(-1, -1), 1);
imshow("腐蚀", dst);
}
//形态学梯度
void Person::gradi(Mat& img)
{
if (img.empty())
{
cout << "图片路径错误" << endl;
return;
}
imshow("原图", img);
Mat gray; Mat binary;
cvtColor(img, gray, COLOR_BGR2GRAY);
Mat Ksize = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
Mat grad; Mat inside; Mat extral; Mat src; Mat src1;
erode(gray, src, Ksize, Point(-1, -1));
dilate(gray, src1, Ksize, Point(-1, -1));
subtract(src1, src, grad);
subtract(gray, src, inside);
subtract(src1, gray, extral);
imshow("形态学", grad);
threshold(grad, grad, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("基本形态学梯度", grad);
}
//黑帽和顶帽
void Person::morph1(Mat& img)
{
imshow("原图", img);
Mat binary = this->myBinary(img);
Mat dst;
Mat rect = getStructuringElement(MORPH_ELLIPSE, Size(14, 14), Point(-1, -1));
imshow("二值化", binary);
//MORPH_TOPHAT
morphologyEx(binary, dst, MORPH_BLACKHAT, rect);
imshow("顶帽", dst);
}
//击中与不击中
void Person::morph2(Mat& img)
{
imshow("原图", img);
Mat dst;
Mat binary = this->myBinary(img);
Mat rect = getStructuringElement(MORPH_CROSS, Size(12, 12), Point(-1, -1));
morphologyEx(binary, dst, MORPH_HITMISS, rect);
imshow("匹配模板", dst);
}
//处理小案列
void Person::case1(Mat& img)
{
Mat dst = Mat::zeros(img.size(), img.type());
if (img.empty())
{
cout << "路径错误" << endl;
return;
}
imshow("原图", img);
Mat src; Mat gray; Mat binary;
GaussianBlur(img, src, Size(3, 3), 0);
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("二值化", binary);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
double are1;
int maxAre = -1;
int index = -1;
cout << contours.size() << endl;
cout << "最终111" << "\t" << index << endl;
for (int i = 0; i < contours.size(); i++)
{
Rect rec = boundingRect(contours[i]);
if (rec.width >= img.cols || rec.height > img.rows) continue;
int area = round( contourArea(contours[i]));
cout << "面积:" << area << endl;
double leng = arcLength(contours[i],true);
if (maxAre < area)
{
maxAre = area;
index = i;
}
}
drawContours(dst, contours, index, Scalar(255, 0, 0), 2, 8);
Mat pts;
approxPolyDP(contours[index], pts, 4, false);
for (int i = 0; i < pts.rows; i++)
{
Vec2i pt = pts.at<Vec2i>(i, 0);
circle(dst, Point(pt[0], pt[1]), 3, Scalar(0, 0, 255), 2, 8);
}
imshow("shuchu ", dst);
}
Opencv图像处理代码
最新推荐文章于 2023-08-01 20:35:12 发布