目录
1、积分图像
2、图像分割--漫水填充
3、图像分割--分水岭法
4、Harris角点检测
1、积分图像
//积分图像
int test1()
{
//创建一个16×16全为1的矩阵,因为256=16×16
Mat img = Mat::ones(16, 16, CV_32FC1);
//在图像中加入随机噪声
RNG rng(10086);
for (int y = 0; y < img.rows; y++)
{
for (int x = 0; x < img.cols; x++)
{
float d = rng.uniform(-0.5, 0.5);
img.at<float>(y, x) = img.at<float>(y, x) + d;
}
}
//计算标准求和积分
Mat sum;
integral(img, sum);
//为了便于显示,转成CV_8U格式
Mat sum8U = Mat_<uchar>(sum);
namedWindow("sum8U", WINDOW_NORMAL);
imshow("sum8U", sum8U);
//计算平方求和积分
Mat sqsum;
integral(img, sum, sqsum);//为了便于显示,转成CV_8U格式
Mat sqsum8U = Mat_<uchar>(sqsum);
namedWindow("sqsum8U", WINDOW_NORMAL);
imshow("sqsum8U", sqsum8U);
//计算倾斜求和积分
Mat tilted;
integral(img, sum, sqsum, tilted);//为了便于显示,转成CV_8U格式
Mat tilted8U = Mat_<uchar>(tilted);
namedWindow("tilted8U", WINDOW_NORMAL);
imshow("tilted8U", tilted8U);
waitKey(0);
return 0;
}
2、图像分割--漫水填充
//图像分割--漫水填充
int test2()
{
system("color 02");//将DOS界面调成白底黑字
Mat img = imread("F:/testMap/lena.png");
if (!(img.data))
{
cout << "读取图像错误,请确认图像文件是否正确" << endl;
return -1;
}
RNG rng(10086);//随机数,用于随机生成像素
//设置操作标志flags
int connectivity = 4;//连通邻域方式
int maskVal = 255;//掩码图像的数值
int flags = connectivity | (maskVal << 8) | FLOODFILL_FIXED_RANGE;//漫水填充操作方式标志
//设置与选中像素点的差值
Scalar loDiff = Scalar(20, 20, 20);
Scalar upDiff = Scalar(20, 20, 20);
//声明掩模矩阵变量
Mat mask = Mat::zeros(img.rows + 2, img.cols + 2, CV_8UC1);
while (true)
{
//随机产生图像中某一像素点
int py = rng.uniform(0, img.rows - 1);
int px = rng.uniform(0, img.cols - 1);
Point point = Point(px, py);
//彩色图像中填充的像素值
Scalar newVal = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
//漫水填充函数
int area = floodFill(img, mask, point, newVal, &Rect(), loDiff, upDiff, flags);
//输出像素点和填充的像素数目
cout << "像素点x: " << point.x << " y : " << point.y << "填充像数数目:" << area << endl;
//输出填充的图像结果
imshow("填充的彩色图像", img);
imshow("掩模图像", mask);
//判断是否结束程序
int c = waitKey(0);
if ((c & 255) == 27)
{
break;
}
}
waitKey(0);
return 0;
}
3、图像分割--分水岭法
//图像分割--分水岭法
int test3()
{
Mat img, imgGray, imgMask, img_;
Mat maskWaterShed; //watershed()函数的参数
img = imread("F:/testMap/lenaw.png"); //含有标记的图像
img_ = imread("F:/testMap/lena.png"); //原图像
cvtColor(img, imgGray, COLOR_BGR2GRAY);
//二值化并开运算
threshold(imgGray, imgMask, 230, 255, THRESH_BINARY);
Mat k = getStructuringElement(0, Size(3, 3));
morphologyEx(imgMask, imgMask, MORPH_OPEN, k);
imshow("含有标记的图像", img);
imshow("原图像", img_);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(imgMask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
//在maskWaterShed上绘制轮廓,用于输入分水岭算法
maskWaterShed = Mat::zeros(imgMask.size(),CV_32S);
for (int index = 0; index < contours.size(); index++)
{
drawContours(maskWaterShed, contours, index, Scalar::all(index + 1), -1, 8, hierarchy, INT_MAX);
}
//分水岭算法需要对原图像进行处理
watershed(img_, maskWaterShed);
vector<Vec3b> colors;// 随机生成几种颜色
for (int i = 0; i < contours.size(); i++)
{
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);
colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
Mat resultImg = Mat(img.size(), CV_8UC3); // 显示图像
for(int i = 0; i < imgMask.rows; i++)
{
for (int j = 0; j < imgMask.cols; j++)
{
//绘制每个区域的颜色
int index = maskWaterShed.at<int>(i, j);
if (index == -1)//区域间的值被置为 - 1(边界)
{
resultImg.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
}
else if (index <= 0 || index > contours.size())//没有标记清楚的区域被置为0
{
resultImg.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
}
else//其他每个区域的值保持不变: 1,2,…,contours.size()
{
resultImg.at<Vec3b>(i, j) = colors[index - 1]; //把些区域绘制成不同颜色
}
}
}
imshow("resultImg", resultImg);
resultImg = resultImg * 0.8 + img_*0.2;
//addWeighted(resultImg,0.8,img_, 0.2,0, resultImg);
imshow("分水岭结果", resultImg);
//绘制每个区域的图像
for (int n = 1; n <= contours.size(); n++)
{
Mat resImagel = Mat(img.size(), CV_8UC3);//声明一个最后要显示的图像
for (int i = 0; i < imgMask.rows; i++)
{
for (int j = 0; j < imgMask.cols; j++)
{
int index = maskWaterShed.at<int>(i, j);
if (index == n)
resImagel.at<Vec3b>(i, j) = img_.at<Vec3b>(i, j);
else
resImagel.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
}
}
//显示图像
imshow(to_string(n), resImagel);
}
waitKey(0);
return 0;
}
4、Harris角点检测
//Harris角点检测
int test4()
{
Mat img = imread("F:/testMap/lena.png", IMREAD_COLOR);
if (!img.data)
{
cout << "读取图像错误,请确认图像文件是否正确" << endl;
return -1;
}
//转成灰度图像
Mat gray;
cvtColor(img, gray,COLOR_BGR2GRAY);
//计算Harris系数
Mat harris;
int blockSize = 2; //邻域半径
int apertureSize = 3;
cornerHarris(gray,harris, blockSize,apertureSize,0.04);
//归一化便于进行数值比较和结果显示
Mat harrisn;
normalize(harris, harrisn, 0, 255, NORM_MINMAX);//将图像的数据类型变成CV_8U
convertScaleAbs(harrisn, harrisn);
//寻找Harris角点
vector<KeyPoint> keyPoints;
for (int row = 0; row < harrisn.rows; row++)
{
for (int col = 0; col < harrisn.cols; col++)
{
int R = harrisn.at<uchar>(row, col);
if (R >125)
{
//向角点存入KeyPoint中
KeyPoint keyPoint;
keyPoint.pt.y =row;
keyPoint.pt.x = col;
keyPoints.push_back(keyPoint);
}
}
}
//绘制角点与显示结果
drawKeypoints(img,keyPoints,img);
imshow("系数矩阵", harrisn);
imshow("Harris角点", img) ;
waitKey(0);
return 0;
}