小目标识别——基于K近邻的白酒杂质检测算法实现
创始人
2024-05-29 10:42:28
0

文章目录

      • 实现思路
      • 配置opencv
      • 位置剪裁
        • 实现代码
      • 自适应中值滤波
        • 实现代码
      • 动态范围增强
        • 实现代码
      • 形态学处理
        • 实现代码
      • 图片预处理效果
      • 计算帧差
        • 连续帧帧差法原理和实现代码
        • 实现代码
      • K近邻实现
        • 基本介绍
      • 实现过程
      • 参考

实现思路

  • 使用C++进行实现,开发平台是clion,并没有使用深度学习,使用opencv进行开发

在这里插入图片描述

配置opencv

  • 一开始就出来幺蛾子,之前装好的opencv怎么都找不到包,弄了一个小时,夹着红框后面的三句,告诉clion我安装的opencv包的具体位置,可能是因为我之前没有编译成功,直接间别人编译好的直接下载下来的,不过我为什么不用python上面的opencv那。

  • 在这里插入图片描述

位置剪裁

在这里插入图片描述

  • 相机位置固定,拍摄的位置固定,背景干扰很少,只需要保存红框右半部分的内容即可,左半部分去除。

实现代码

#include 
#include 
#include 
#include 
#include using namespace std;
using namespace cv;struct RectPoint{int x,y;int width,height;RectPoint(int x,int y,int width,int height):x(x),y(y),width(width),height(height){}
};void ClipImage(String ImagePath,RectPoint rect,String TargetPath){// 声明Mat保存图片Mat img;Rect m_select;string line;// 判定文件存在ifstream input_file(ImagePath);if (!input_file.is_open()) {cerr << "Could not open the file - '"<< ImagePath << "'" << endl;return;}while(getline(input_file,line)){// 获取文件后缀名,并进行拼接成目标文件名string ImageName = line.substr(line.find_last_of('\\',line.size())+1);string TargetName = TargetPath;TargetName.append(ImageName);// 读取并剪裁图片到特定大小保存img = imread(line);m_select = Rect(rect.x,rect.y,rect.width,rect.height);Mat ROI = img(m_select);imwrite(TargetName,ROI);}
}int main()
{String TargetImage = R"(E:\CProject\impurityDetection\ClippedImage\)";String SourceImage = R"(E:\CProject\impurityDetection\image\path.txt)";ClipImage(SourceImage,RectPoint(600,0,1780,1480),TargetImage);return 0;
}

自适应中值滤波

  • 自适应中值滤波,是为了去除照相机的噪声同时,又不损坏原来的杂质信息,这里使用自适应中值滤波,具体实现如下。

在这里插入图片描述

实现代码

void Convolution(Mat &SourceImage,vector &pixels,int x,int y ,int border){for (int k = -border; k <= border; k++){for (int l = -border; l <= border; l++){pixels.push_back(SourceImage.at(x+k, y+l));}}
}Mat SelfAdaptMedianFilter(const Mat& SourceImage){// 复制原图Mat result = SourceImage.clone();// 掩膜大小为3int ksize = 3;int border = ksize /2 ;for (int i = border; i < SourceImage.rows - border; i++){for (int j = border; j < SourceImage.cols - border; j++){while(1){// 提取当前像素的邻域vector pixels;Convolution(result, pixels, i, j, border);// 对邻域像素值进行排序sort(pixels.begin(), pixels.end());// 取中值作为当前像素的新值int median = pixels[pixels.size() / 2];int PMax = pixels[pixels.size() - 1];int PMin = pixels[0];//判定是否为异常值if (median == PMax || median == PMin) {// 掩膜再加2,重新计算ksize += 2;if (ksize + 2 > Nmax) {result.at(i, j) = median;break;}else{// 判定传入的值,是否出现越界的情况if((i - ksize / 2 < 0 || i + ksize / 2 < SourceImage.cols) ||j - ksize / 2 < 0 || j + ksize / 2 > SourceImage.rows)result.at(i,j) = (PMax + PMin) / 2;}} else {//中值不是极值,判定原像素点是不是极值,然后在进行输出if (result.at(i, j) == PMax || result.at(i, j) == PMin)result.at(i,j) = median;break;}}}}return result;
}

动态范围增强

  • 这里就是图像的直方图均衡化,使得整个模型的图片颜色对比度更大,显示出更多的细节。

实现代码

   //对图片进行直方图均衡化,凸显出前后差异Mat equalized;// 转成二值化,并变为直方图均衡化cvtColor(ROI, equalized, COLOR_BGR2GRAY);equalizeHist(equalized, equalized);

形态学处理

  • 膨胀操作 :通过增加图像中的物体的像素数量,使得物体的大小和面积增加,边缘变得更加明显,改变了原来字体粗细

在这里插入图片描述

  • 腐蚀操作 :在卷积核大小中对图片进行卷积。取图像中(3 * 3)区域内的最小值。可以消除图像中的毛刺和噪声。改变了原来字体粗细
    在这里插入图片描述
  • 开运算 :先腐蚀运算,在进行膨胀运算。在不损害字体信息的情况下,去除了噪声和毛刺。通过调整卷积可以进一步减少噪声

在这里插入图片描述

  • 闭运算 :先膨胀运算,在进行腐蚀运算。在不去除任何噪声的情况下,补全了缺失的信息。

在这里插入图片描述

  • 这里选择开运算,具体实现代码如下,别的可以参考知乎链接

实现代码

   // 对图像进行开运算,Mat morphologied;int size = 3;// shape是内核的形状,size是内核的尺寸,锚点的位置,对于矩形来说,全部都是 1 ,不用调整cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(2*size + 1, 2*size+1),cv::Point(size, size));cout<

图片预处理效果

在这里插入图片描述

计算帧差

  • 主要有两种方法,分别是静态参考帧差分法和连续帧帧差法,下图为两个效果,很明显的可以就看到连续帧帧差法的效果更好,常见的静态帧是将多个帧进行平均,然后以平均之后的帧作为参考帧,然后后面每帧都是和当前帧作比较,没有动作的连续性。

在这里插入图片描述
在这里插入图片描述

连续帧帧差法原理和实现代码

  • 实现原理如下图
    在这里插入图片描述

  • 使用absdiff函数,具体描述如下,计算frame1和frame2的帧差,然后将结果保存到framediff中

cv::Mat frameDiff;
cv::absdiff(frame1, frame2, frameDiff);

实现代码


//计算帧差,并将最终的结果进行返回
Mat DifFrame(Mat PreFrame,Mat CurFrame,Mat NextFrame){//计算帧差Mat FrameDiffPre , FrameDiffNext;absdiff(PreFrame,CurFrame,FrameDiffPre);absdiff(CurFrame,NextFrame,FrameDiffNext);// 分别进行二值化,设定二值化的阈值Mat BinImgPre , BinImgNext;threshold(FrameDiffPre,BinImgPre,128,255,cv::THRESH_BINARY);threshold(FrameDiffNext,BinImgPre,128,255,cv::THRESH_BINARY);// 将图片进行与运算,然后将结果进行输出Mat ResFrame;bitwise_and(FrameDiffPre,FrameDiffNext,ResFrame);//返回最终处理过后的帧return ResFrame;}

K近邻实现

基本介绍

  • 思路 : 将样本在特征空间中,根据一定的分类方法,归类于与该样本最相似的K个样本中大多数的那一类。需要一部分已经标注过的样本,然后将未标注过的样本进行分类。
  • 特点

实现过程

参考

  • Opencv 图像处理之膨胀与腐蚀 【https://zhuanlan.zhihu.com/p/110330329】

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...