重映射
remap()函数
//【0】变量定义
Mat srcImage, dstImage;
Mat map_x, map_y;
//【1】载入原始图
srcImage = imread("dota_pa.jpg", 1);
if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
imshow("原始图", srcImage);
//【2】创建和原始图一样的效果图,x重映射图,y重映射图
dstImage.create(srcImage.size(), srcImage.type());
map_x.create(srcImage.size(), CV_32FC1);
map_y.create(srcImage.size(), CV_32FC1);
//【3】双层循环,遍历每一个像素点,改变map_x & map_y的值
for (int j = 0; j < srcImage.rows; j++)//注意rows是行数,即y轴方向
{
for (int i = 0; i < srcImage.cols; i++)
{
//改变map_x & map_y的值.
map_x.at<float>(j, i) = static_cast<float>(i);//点(x,y)的第一个映射,即对应的是i
map_y.at<float>(j, i) = static_cast<float>(srcImage.rows - j);
}
}
//【4】进行重映射操作
remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
map_x, map_y表示第一个映射和第二个映射,若 map_x表示(x,y),则map_y不代表任何值;第五个是插值方式,类同resize();边界模式;默认值。上面实例就是x不动,y做了一个对称变化,y=max - y
仿射变换
warpAffine()——重映射,getRotationMatrix2D()来获得旋转矩阵
直方图均衡化
垃圾电脑,全部没了
有RNG随机数,寻找轮廓,凸包,贴两端代码吧,下面是轮廓:
#define WINDOW_NAME1 "【原始图窗口】"
#define WINDOW_NAME2 "【轮廓图】"
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector<vector<Point>> g_vContours;
vector<Vec4i> g_vHierarchy;
void on_ThreshChange(int, void*);
int main(int argc, char** argv)
{
system("color 1F");
// 加载源图像
g_srcImage = imread("zhifang.jpg", 1);
resize(g_srcImage, g_srcImage, Size(), 0.3, 0.3);
// 转成灰度并模糊化降噪
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
blur(g_grayImage, g_grayImage, Size(3, 3));
// 创建窗口
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME1, g_srcImage);
//创建滚动条并初始化
createTrackbar("canny阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);
on_ThreshChange(0, 0);
waitKey(0);
return(0);
}
void on_ThreshChange(int, void*)
{
// 用Canny算子检测边缘
Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);
// 寻找轮廓
findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
//8位单通道二值图;点向量的vector;每个轮廓包含四个轮廓元素,可选的输出向量;轮廓检索模式,这个是提取所有的轮廓,还有RETR_EXTERNAL提取最外层的等等;轮廓的近似办法;轮廓点的偏移量,默认0
// 绘出轮廓
Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
for (int i = 0; i< g_vContours.size(); i++)
{
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值
drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());
//目标图像,点向量vector,绘制的指示变量,负数绘制所有
}
// 显示效果图
imshow(WINDOW_NAME2, drawing);
}
凸包:(RNG随机生成器)
Mat image(600, 600, CV_8UC3);
RNG& rng = theRNG();
//循环,按下ESC,Q,q键程序退出,否则有键按下便一直更新
while (1)
{
//参数初始化
char key;//键值
int count = (unsigned)rng % 100 + 3;//随机生成点的数量3-103,前闭后开
vector<Point> points; //点值
//随机生成点坐标
for (int i = 0; i < count; i++)
{
Point point;
point.x = rng.uniform(image.cols / 4, image.cols * 3 / 4);
point.y = rng.uniform(image.rows / 4, image.rows * 3 / 4);
points.push_back(point);
}
//检测凸包
vector<int> hull;
convexHull(Mat(points), hull, true);
//绘制出随机颜色的点
image = Scalar::all(0);
for (int i = 0; i < count; i++)
circle(image, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, LINE_AA);
//准备参数
int hullcount = (int)hull.size();//凸包的边数
Point point0 = points[hull[hullcount - 1]];//连接凸包边的坐标点
//绘制凸包的边
for (int i = 0; i < hullcount; i++)
{
Point point = points[hull[i]];
line(image, point0, point, Scalar(255, 255, 255), 2, LINE_AA);
point0 = point;
}
//显示效果图
imshow("凸包检测示例", image);
//按下ESC,Q,或者q,程序退出
key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q')
break;
}
return 0;
寻找最小包围圆形,矩形,多边形等,分别为minAreaRect()输入二维点集;minEnclosingCircle输入点集,输出圆心,半径;(),approxPolyDP()