5.10-OpenCV学习(7)

本文介绍了使用OpenCV进行图像处理的方法,包括重映射、轮廓检测及凸包绘制等内容,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重映射
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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值