首页 > 其他分享 >数字图像处理-实验2

数字图像处理-实验2

时间:2024-09-17 21:36:56浏览次数:1  
标签:bimg Mat int 数字图像处理 cols 实验 fimg cv

实验E2:图像代数运算

实验2.1:对比度调整

设计一个Sigmoid函数,实现对图像的对比度调整,并使得调整幅度可以通过参数控制;

通过查阅资料得知,Sigmoid函数的标准形式为:

其中,

x 表示输入的像素值,并且可以归一化到[0,1]范围内。

k 表示的是控制对比度调整幅度的参数,k 值越大,图像的对比度越高;k 值越小,对比度越低。

x0 参数用来调整Sigmoid函数的中心点,通过查阅资料可知该参数的值一般取 0.5 。

 

据此编写出Sigmoid函数的代码:

inline float sigmoid(float x,float k,float x0){
    return 1.0/(1.0+exp(-k*(x-x0)));
}

利用Sigmoid函数调整图像对比度的代码如下:

cv::Mat contrast_adjust(const cv::Mat& src,float k,float x0){
    cv::Mat dst=cv::Mat::zeros(src.size(),src.type());
    for(int i=0;i<src.rows;++i){
        for(int j=0;j<src.cols;++j) {
            for (int c=0;c<src.channels();++c) {
                //归一化到[0,1]
                float pixel=src.at<cv::Vec3b>(i,j)[c]/255.0;
                float adjusted=sigmoid(pixel,k,x0);
                //映射回[0,255]
                dst.at<cv::Vec3b>(i,j)[c]=cv::saturate_cast<uchar>(adjusted*255);
            }
        }
    }
    return dst;
}

测试结果如下:

当k=3,x0=0.5时,原图(上)和调整后的图片(下)的对比如下:

当k=80,x0=0.4时,图像的对比如下:

 

实验2.2:背景相减

•对图像I和对应的背景图B,基于背景相减检测I中的前景区域,并输出前景的mask.

•分析你的方法可能产生误检的情况,并上网查阅背景相减的改进方法,设法改进结果。

•测试数据见群文件bgs-data.zip

首先能够自然而然地想到一种朴素的方法:遍历前景图和背景图中的每一个点,计算对应像素点的每一种颜色数值之间的差的平方和,即它们之间的欧氏距离。如果这个距离小于某个阈值那么就认为这两个像素之间是一样的,并在结果图中去掉这个像素点。利用这个朴素算法进行背景相减的实验代码如下:

int main(int argc,char *argv[]){
    cv::Mat fimg=cv::imread("2-2_f.png");
    cv::Mat bimg=cv::imread("2-2_b.png");
    if(fimg.empty()||bimg.empty()||fimg.rows!=bimg.rows||fimg.cols!=bimg.cols){
        std::cout<<"Illegal Input!"; return 0;
    }
    cv::Mat res=cv::Mat::zeros(fimg.size(),fimg.type());
    for(int i=0;i<fimg.rows;++i){
        for(int j=0;j<fimg.cols;++j){
            double dis=0; //距离
            for(int k=0;k<3;++k){
                dis+=std::pow(fimg.at<cv::Vec3b>(i,j)[k]-bimg.at<cv::Vec3b>(i,j)[k],2);
            }
            if(dis<5000) res.at<cv::Vec3b>(i,j)={0,0,0};
            else res.at<cv::Vec3b>(i,j)=fimg.at<cv::Vec3b>(i,j);
        }
    }
    cv::imshow("output",res);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

当阈值分别取100,1000,5000,10000时,实验结果如下:

可以看到,朴素算法的处理结果中要么去除不干净背景,要么就连背景和需要保留的人一起去除了,总之效果不是太好。

因此又去寻找有关背景相减的改进算法,了解到了一种比较通用的处理算法:

仔细研究后发现这个方法好像和我的朴素算法基本一样,因此又尝试在这个算法的基础上进行改进。想到可以对每一个像素点和它周围的几个像素点做平均,利用平均后的值再进行上面的步骤,这次的实验结果如下:

实验代码
 int main(int argc,char *argv[]){
    cv::Mat fimg=cv::imread("2-2_f.png");
    cv::Mat bimg=cv::imread("2-2_b.png");
    if(fimg.empty()||bimg.empty()||fimg.rows!=bimg.rows||fimg.cols!=bimg.cols){
        std::cout<<"Illegal Input!"; return 0;
    }
    cv::Mat res=cv::Mat::zeros(fimg.size(),fimg.type());
    int max_step=1;
    int dx[]={-1,-1,0,1,1,1,0,-1},dy[]={0,1,1,1,0,-1,-1,-1};
    for(int i=0;i<fimg.rows;++i){
        for(int j=0;j<fimg.cols;++j){
            double dis=0; //距离
            cv::Vec3b avg=bimg.at<cv::Vec3b>(i,j);
            //std::cout<<avg<<"|";
            int avg_cnt=1;
            for(int step=1;step<=max_step;++step){
                for(int twd=0;twd<8;++twd){
                    int ni=i+dx[twd]*step,nj=j+dy[twd]*step;
                    if(ni<0||ni>=fimg.rows||nj<0||nj>=fimg.cols) continue;
                    ++avg_cnt;
                    avg+=bimg.at<cv::Vec3b>(ni,nj);
                }
            }
            avg=avg/avg_cnt;
            //std::cout<<avg<<std::endl;

            cv::Vec3b avgf=fimg.at<cv::Vec3b>(i,j);
            //std::cout<<avg<<"|";
            int avg_cntf=1;
            for(int step=1;step<=max_step;++step){
                for(int twd=0;twd<8;++twd){
                    int ni=i+dx[twd]*step,nj=j+dy[twd]*step;
                    if(ni<0||ni>=fimg.rows||nj<0||nj>=fimg.cols) continue;
                    ++avg_cntf;
                    avgf+=fimg.at<cv::Vec3b>(ni,nj);
                }
            }
            avgf=avgf/avg_cntf;


            for(int k=0;k<3;++k){
                dis+=std::pow(avgf[k]-avg[k],2);
            }
            if(dis<1) res.at<cv::Vec3b>(i,j)={0,0,0};
            else res.at<cv::Vec3b>(i,j)=fimg.at<cv::Vec3b>(i,j);
        }
    }
    cv::imshow("output",res);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

可以看到,效果还是不理想。

之后又想到了一种优化方法:在朴素算法计算完成后再对结果图遍历一遍,对每个像素点计算它周围有多少个被删除了的点和有多少个没被删除的点,如果被删除的点的比例高于某个阈值,就把它也删除掉;如果它周围没被删除的点的比例高于某个阈值,就把前景图中对应点的像素赋给它。此方法的实验代码如下:

bool del_map[5000][5000],rec_map[5000][5000];
int main(int argc,char *argv[]){
    cv::Mat fimg=cv::imread("2-2_f.png");
    cv::Mat bimg=cv::imread("2-2_b.png");
    if(fimg.empty()||bimg.empty()||fimg.rows!=bimg.rows||fimg.cols!=bimg.cols){
        std::cout<<"Illegal Input!"; return 0;
    }
    cv::Mat res=cv::Mat::zeros(fimg.size(),fimg.type());
    for(int i=0;i<fimg.rows;++i){
        for(int j=0;j<fimg.cols;++j){
            double dis=0; //距离
            for(int k=0;k<3;++k){
                dis+=std::pow(fimg.at<cv::Vec3b>(i,j)[k]-bimg.at<cv::Vec3b>(i,j)[k],2);
            }
            if(std::sqrt(dis)<100) res.at<cv::Vec3b>(i,j)={0,0,0};
            else res.at<cv::Vec3b>(i,j)=fimg.at<cv::Vec3b>(i,j);
        }
    }
    cv::imshow("ori",res);
    int max_step=10;
    int dx[]={-1,-1,0,1,1,1,0,-1},dy[]={0,1,1,1,0,-1,-1,-1};
    double erase_rate=0.1,recover_rate=0.2;
    for(int i=0;i<fimg.rows;++i){
        for(int j=0;j<fimg.cols;++j){
            int tot=0,del_cnt=0;
            for(int step=1;step<=max_step;++step){
                for(int twd=0;twd<8;++twd){
                    int ni=i+dx[twd]*step,nj=j+dy[twd]*step;
                    if(ni<0||ni>=fimg.rows||nj<0||nj>=fimg.cols) continue;
                    ++tot;
                    if(res.at<cv::Vec3b>(ni,nj)==cv::Vec3b{0,0,0}) ++del_cnt;
                }
            }
            if(del_cnt*1.0/tot>=erase_rate) del_map[i][j]=true;
            if((tot-del_cnt)*1.0/tot>=recover_rate) rec_map[i][j]=true;
        }
    }
    for(int i=0;i<fimg.rows;++i){
        for(int j=0;j<fimg.cols;++j){
            if(del_map[i][j]) res.at<cv::Vec3b>(i,j)={0,0,0};
            if(rec_map[i][j]) res.at<cv::Vec3b>(i,j)=fimg.at<cv::Vec3b>(i,j);
        }
    }
    cv::imshow("output",res);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

当阈值取100,删除比例取0.1,恢复比例取0.2时,原方法(左)和改进方法(右)的效果如下:

可以看到,优化后的方法在效果上对比原方法还是有一定的改进的。

标签:bimg,Mat,int,数字图像处理,cols,实验,fimg,cv
From: https://www.cnblogs.com/Nartsam/p/18417558

相关文章

  • 山东大学可视化2024第一次实验
    问题:画出美国1900与2000人口分布介绍:只是一个非常粗糙的可视化模板,注意后续改一下颜色什么的~步骤:1.安装vscode2.下载安装图片中插件3.新建一个文件夹并添加到工作区4.创建一个html文件5.将数据粘贴到文件夹中6.将以下代码粘贴到html文件中<!DOCTYPEhtml><h......
  • TCP协议分析《实验报告》
    一、实验目的1、理解TCP协议;2、掌握TCP协议三次握手建立连接和四次挥手释放连接的过程;3、理解TELNET协议及工作过程;4、掌握TCP协议分析方法。二、实验设备和环境1、硬件设备:PC机或笔记本电脑;2、软件:H3CCloudLab、Wireshark。三、实验记录1、实验环境搭建按照下图在......
  • Linux 基础入门操作-实验二 makefile使用介绍 和 实验三 hello 输出
    1介绍Makefile是linux下的项目管理工具,想象一下当有很多源文件需要编译、链接时,你只需执行make命令即可完成编译操作,这样是不是很方便呢。make命令执行时,需要一个Makefile文件,用来告诉make命令需要怎么样的去编译和链接程序,下面详细介绍Makefile的使用与书写规......
  • Telnet的连接实验
    Telnet的连接实验Windows7虚拟机的Telnet服务由于windows11已经将telnet服务器端移除,为了测试Telnet的连接,要安装Windows7的虚拟机安装VMWare(点击图片跳转)安装光盘在VMVare安装Window7选典型安装在主机Window11/10这边打开客户端服务对虚拟机打开Telnet服......
  • 实验(?)
    虽然没有被叫走,但是鉴于我是生物大神,所以我也跟着去了科教馆二楼还有个录播教室,进去一看,录的实验选题是“淀粉-淀粉酶体系能否进行‘不同ph对酶反应活性的影响’实验”一上来先问我们,觉得淀粉无酶和酸性条件下是不是会水解,鉴于之前上课讲过一个类似的可逆反应,所以就一致回......
  • Springboot高校实验室管理系统s558a--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景随着高等教育的快速发展,高校实验室作为科研与教学的重要基地,其管理效率与资源利用水平直接影响到教学与科研的质量。传统的手工管理模......
  • 数据结构实验第一周
    6-1差距几何排序的话复杂度要O(n),可以选择桶排序或者计数排序,我选择的是计数排序比如是32144786我开一个数组a[9](因为最大为8),然后分别对出现的数计数有a:111201110然后按顺序放回就是12344678intfun(intD[],intN){if(N<2)return0;......
  • 【隐私计算】Cheetah安全多方计算协议-阿里安全双子座实验室
    2PC-NN安全推理与实际应用之间仍存在较大性能差距,因此只适用于小数据集或简单模型。Cheetah仔细设计DNN,基于格的同态加密、VOLE类型的不经意传输和秘密共享,提出了一个2PC-NN推理系统Cheetah,比CCS'20的CrypTFlow2开销小的多,计算效率更快,通信效率更高。主要贡献有两点:基于格......
  • SSM实验室管理系统
    101开发语言:Java数据库:MySQL5.7技术:SSM工具:IDEA/Ecilpse、Navicat、Maven需求分析1.1需求分析概述生活中的实验室管理系统很复杂,对安全性和完整性要求都很高。在此我运用数据库课上所学知识,结合自己平时的操作业务体验,认为一个合格的实验室管理系统至少应该具备以下几点要......
  • 《DNK210使用指南 -CanMV版 V1.0》第二十四章 LCD显示实验
    第二十四章LCD显示实验1)实验平台:正点原子DNK210开发板2)章节摘自【正点原子】DNK210使用指南-CanMV版V1.03)购买链接:https://detail.tmall.com/item.htm?&id=7828013987504)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html5)正点原......