基于形心的目标检测方法

用VisualStudio和OpenCV实现,包括BMP文件读取、固定阈值分割、大津阈值分割、迭代法分割、目标形心的确定、目标框的确定等。

Object_Detection.h
#include <iostream>
#include <opencv2\opencv.hpp>
#include <math.h>
#include <stdlib.h>
#include <Windows.h>using namespace cv;
using namespace std;int value=0;
Mat srcImg, dstImg;Rect getRoi(Mat src);
void binaryzation(Mat src);
Mat fixedThreshold(Mat src, int thresh);
void on_trackbar(int,void*);
int OtsuBinary(Mat src);
void drawTracker(Mat src);
Point getEdgePoint(Mat src);
Point getCenterPoint(Mat src);
int iterationBinary(Mat src);
uchar * readBMP(char *bmpName, int *width, int *height);

Object_Detection.cpp
#include "Object_Detection.h"int main() {int width, height;char c = 0;Rect roi;char *codingFileout = "plane1.bmp";unsigned char *img = readBMP(codingFileout, &width, &height);uchar **tempimg = new  uchar *[height];for (int i = 0; i < height; i++) {tempimg[i] = new uchar[width];}//cout << width << "," << height;for (int i = 0; i <height; i++) {for (int j = 0; j <width; j++) {tempimg[height-1-i][j] = *(img + i*width + j);//cout << tempimg[i][j] << " ";}}//*(buf + i*lineByte + j) = *(imgBuf + i*width*byteCount + j);Mat temp(height,width, CV_8UC1);cout << temp.rows << "," << temp.cols;for (int i = 0; i < height; i++) {uchar *data = temp.ptr<uchar>(i);for (int j = 0; j < width; j++) {//tempimg[i][j] = *img + i*width + j;data[j] = tempimg[i][j];}}cout << temp.rows << "," << temp.cols;//cout << temp.channels();imshow("1", temp);srcImg = temp.clone();//srcImg = imread("plane2.bmp", CV_LOAD_IMAGE_UNCHANGED);//预处理roi = getRoi(srcImg);srcImg=Mat(srcImg,roi).clone();//若输入为RGB彩图,则灰度化//cvtColor(srcImg, srcImg, CV_BGR2GRAY);//进行简单滤波处理medianBlur(srcImg, srcImg, 3);//GaussianBlur(srcImg, srcImg, Size(3, 3),0,0);//blur(srcImg, srcImg, Size(5, 5));while (c != 27) {system("cls");binaryzation(srcImg);drawTracker(dstImg);cout << "按Esc键退出,其他键重复操作!" << endl;c = waitKey(0);destroyAllWindows();}return 0;
}
uchar * readBMP(char *bmpName, int *width, int *height) {FILE *fp;fopen_s(&fp, bmpName, "rb");if (fp == 0) return 0;fseek(fp, sizeof(BITMAPFILEHEADER), 0);int w, h, b;BITMAPINFOHEADER head;fread(&head, sizeof(BITMAPINFOHEADER), 1, fp);w = head.biWidth;h = head.biHeight;* width = w, * height = h;b = head.biBitCount / 8;int lineByte = (w * b + 3) / 4 * 4;if (b == 1)fseek(fp, 1024, 1);unsigned char *imgBuf = new unsigned char[w * h * b];for (int i = 0; i<h; i++){fread(imgBuf + i*w*b, w*b, 1, fp);fseek(fp, lineByte - w*b, 1);}fclose(fp);return imgBuf;
}void binaryzation(Mat src) {char funOfBinary=0, funOfExit=0;int thresholdOfImg=0;cout << "请输入二值化方法:" << endl;cout << "                 固定法求阈值为 1" << endl;cout << "                 大津法求阈值为 2" << endl;cout << "                 迭代法求阈值为 3" << endl;cout << "选择的方法为:";cin >> funOfBinary;switch (funOfBinary){case('1'):namedWindow("Fixed Threshold");createTrackbar("Threshold 100", "Fixed Threshold", &value, 255, on_trackbar);on_trackbar(value, 0);cout << "请按ESC键进行目标选定" << endl;funOfExit=waitKey(0);while (funOfExit != 27) {cout << "输入错误,请重新输入" << endl;funOfExit = waitKey(0);}cout << "选择的阈值为:" << value << endl;break;case('2'):namedWindow("OTSU Binaryzation");thresholdOfImg = OtsuBinary(srcImg);cout << "使得类间方差最大的阈值为:" << thresholdOfImg << endl;dstImg = fixedThreshold(srcImg, thresholdOfImg);imshow("OTSU Binaryzation", dstImg);cout << "请按ESC键进行目标选定" << endl;funOfExit = waitKey(0);while (funOfExit != 27) {cout << "输入错误,请重新输入" << endl;funOfExit = waitKey(0);}break;case('3'):namedWindow("Iteration Binaryzation");thresholdOfImg = iterationBinary(srcImg);cout << "迭代的阈值为:" << thresholdOfImg << endl;dstImg = fixedThreshold(srcImg, thresholdOfImg);imshow("Iteration Binaryzation", dstImg);cout << "请按ESC键进行目标选定" << endl;funOfExit = waitKey(0);while (funOfExit != 27) {cout << "输入错误,请重新输入" << endl;funOfExit = waitKey(0);}break;default:return;}
}void on_trackbar(int,void*) {//cout << value << endl;dstImg = fixedThreshold(srcImg, value);imshow("Fixed Threshold", dstImg);
}
Mat fixedThreshold(Mat src,int thresh) {Mat dst;dst = src.clone();for (int i = 0; i < src.rows; i++) {uchar *dataSrc = src.ptr<uchar>(i);uchar *dataDst= dst.ptr<uchar>(i);for (int j = 0; j < src.cols; j++) {if (dataSrc[j] >= thresh) {dataDst[j] = 255;}else {dataDst[j] = 0;}}}return dst;
}int OtsuBinary(Mat src) {int numOfEveryGayPixel[256] = { 0 };float percentOfEveryPixel[256] = { 0 };float averageGrayOfForeground = 0;float averageGrayOfImg = 0;float percentOfForeground = 0;float tempAverageGrayOfForeground = 0;float curVariance=0,maxVariance = 0;int thresholdOfOtsu =0;//得到灰阶直方图for (int i = 0; i < src.rows; i++) {uchar *data = src.ptr<uchar>(i);for (int j = 0; j < src.cols; j++) {numOfEveryGayPixel[(int)data[j]]++;}}//得到每个灰阶像素数目占比for (int i = 0; i < 256; i++) {percentOfEveryPixel[i] = (float)numOfEveryGayPixel[i] / (src.rows*src.cols);averageGrayOfImg = averageGrayOfImg + i*percentOfEveryPixel[i];}//检测类间方差最大的灰阶阈值for (int i = 0; i < 256; i++) {//假设i为最佳阈值//u=w0×u0+w1×u1//g = w0×(u0−u)2 + w1×(u1−u)2//g = w0/(1−w0)×(u0−u)2percentOfForeground = percentOfForeground + percentOfEveryPixel[i];tempAverageGrayOfForeground = tempAverageGrayOfForeground + i*percentOfEveryPixel[i];averageGrayOfForeground = tempAverageGrayOfForeground / percentOfForeground;curVariance = percentOfForeground *pow((averageGrayOfImg - averageGrayOfForeground), 2) / (1 - percentOfForeground);if (curVariance > maxVariance) {maxVariance = curVariance;thresholdOfOtsu = i;}}return thresholdOfOtsu;
}Point getCenterPoint(Mat src) {int xTotal = 0, yTotal = 0,sumPixel=0;Point centerPoint;for (int i = 0; i < src.rows; i++) {uchar *data = src.ptr<uchar>(i);for (int j = 0; j < src.cols; j++) {if (data[j] == 255) {xTotal += j;yTotal += i;sumPixel += 1;}}}centerPoint.x = xTotal / sumPixel;centerPoint.y = yTotal / sumPixel;return centerPoint;
}Point getEdgePoint(Mat src) {Point EdgePoint=Point(400,400);bool flag = false;for (int i = 0; i < src.rows; i++) {uchar *data = src.ptr<uchar>(i);for (int j = 0; j < src.cols-2; j++) {if (data[j] == 255&& data[j+2] == 255) {flag = true;EdgePoint.y = i;break;}}if (flag) {break;}}flag = false;for (int i = 0; i < src.cols-2; i++) {for (int j = 0; j < src.rows-2; j++) {uchar *data = src.ptr<uchar>(j);if (data[i]== 255 && data[i+2]==255) {flag = true;EdgePoint.x = i;break;}}if (flag) {break;}}return EdgePoint;
}void drawTracker(Mat src) {Mat tepmSrc = srcImg.clone();cout << "目标形心为:" << endl;Point centerPoint = getCenterPoint(src);Point edgePoint = getEdgePoint(src);Point edgeThreshold = Point(8, 8);cout << "           (" << centerPoint.x << "," << centerPoint.y << ")" << endl;rectangle(tepmSrc, edgePoint-edgeThreshold, 2 * centerPoint - edgePoint+ 2 * edgeThreshold, Scalar(0,0,255), 2,8,0);namedWindow("Track Object");imshow("Track Object", tepmSrc);//char funOfExit = waitKey(0);
}int iterationBinary(Mat src) {//直方图统计  int histData[256] = { 0 };int sumPixelOfBack = 0, sumPixelOfFore = 0, sumOfFore = 0, tempThreshold;int thresholdOfImg = 0;for (int i = 0; i < src.rows; i++){uchar *data = src.ptr<uchar>(i);for (int j = 0; j < src.cols; j++){histData[data[j]]++;}}//求图像的平均灰度值作为初始阈值  for (int i = 0; i < 256; i++){thresholdOfImg += i * histData[i];}thresholdOfImg /= src.rows *src.cols;tempThreshold = thresholdOfImg;//迭代  while (true){sumPixelOfBack = 0, sumPixelOfFore = 0, sumOfFore = 0;for (int i = 0; i < thresholdOfImg + 1; i++){sumPixelOfBack += i * histData[i];}for (int i = thresholdOfImg + 1; i < 256; i++){sumPixelOfFore += i * histData[i];sumOfFore += histData[i];}tempThreshold = (sumPixelOfBack /(src.rows *src.cols- sumOfFore) + sumPixelOfFore / sumOfFore) / 2;//cout << tempThreshold << endl;if (tempThreshold == thresholdOfImg){break;}else{thresholdOfImg = tempThreshold;}}return tempThreshold;
}Rect getRoi(Mat src) {int height = src.rows, width = src.cols;int minX=0, maxX= width, minY=0, maxY= height;int sum1 = 0,sum2=0;int flag1 = 1, flag2 = 1;cout << height;Rect rect;for (int i = 0; i < int(height/4); i++) {sum1 = 0, sum2 = 0;uchar *data1 = src.ptr<uchar>(i);uchar *data2 = src.ptr<uchar>(height -i-1);for (int j = 0; j < width; j++) {//默认低于5为黑边if (data1[j] <= 30) {sum1++;}if (data2[j] <= 30) {sum2++;}}flag1 = 1, flag2 = 1;//默认每行大于(宽度-20)个像素点为黑边if(sum1>width  / 5){minY = i+1;flag1 = 0;}if (sum2>width  / 5) {maxY = height - i-1;flag1 = 0;}if (flag1&&flag2) {break;}}for (int i = 0; i < int(width /4); i++) {sum1 = 0, sum2 = 0;for (int j = 0; j < height; j++) {uchar *data = src.ptr<uchar>(j);//默认低于5为黑边if (data[i] <= 30) {sum1++;}if (data[width -i] <= 30) {sum2++;}}flag1 = 1, flag2 = 1;//默认每行大于(宽度-20)个像素点为黑边if (sum1>height / 5) {minX = i+1;flag1 = 0;}if (sum2>height / 5) {maxX = width - i-1;flag1 = 0;}if (flag1&&flag2) {break;}}rect= Rect(minX, minY, maxX-minX,maxY-minY);return rect;
}

基于形心的目标检测方法相关推荐

  1. 自动驾驶采标系列四:基于激光雷达的目标检测方法

        标注猿的第55篇原创        一个用数据视角看AI世界的标注猿   上一篇文章我们讲了基于图像的目标检测技术,但对于标注人员来说这部分内容就相对比较难一些,只是作为一个了解就可以,但是如 ...

  2. Facebook AI的DETR:一种基于Transformer的目标检测方法

    介绍 机器学习框架或库有时会更改该领域的格局.前不久,Facebook开源了一个这样的框架,DETR(DEtection TRansformer) 在本文中,我们将快速了解目标检测的概念,然后研究DE ...

  3. 一文览尽基于激光雷达点云(lidar)的目标检测方法

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 本文来源:计算机视觉之路,作者:山涧一壶酒,编辑:智车科技 / 导读 / 上周文章:自动驾驶中的激光雷 ...

  4. 基于深度学习的目标检测方法综述

    引言 现有的深度学习的目标检测方法,可以大致分为两类:一.基于候选区域的目标检测方法:二.基于回归的目标检测方法.依据方法的提出时间,可以构建出如下时间线: 2014 CVPR R-CNN[1] 20 ...

  5. 一文览尽LiDAR点云目标检测方法

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 转载于 :计算机视觉之路,作者:山涧一壶酒 / 导读 / 自动驾驶中的激光雷达点云如何做特征表达,将基 ...

  6. matlab基于ssd的角点匹配_基于关键点的目标检测

    0 1 前言:基于锚点的目标检测方法 在基于关键点(key points)的目标检测方法出现之前,主流目标检测方法一般先设置一些预先定义好的 锚点 (anchor boxes). 作为预测物体框的参考 ...

  7. 【目标检测】0、目标检测方法发展综述

    引言 目标检测: 目标检测的目标是确定某张给定图像中是否存在给定类别(比如人.车.自行车.狗和猫)的目标实例:如果存在,就返回每个目标实例的空间位置和覆盖范围(比如返回一个边界框). 目标检测的意义 ...

  8. 基于CNN目标检测方法(RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN,YOLO,SSD)行人检测,目标追踪,卷积神经网络

    一.研究意义 卷积神经网络(CNN)由于其强大的特征提取能力,近年来被广泛用于计算机视觉领域.1998年Yann LeCun等提出的LeNet-5网络结构,该结构使得卷积神经网络可以端到端的训练,并应 ...

  9. 值得收藏!基于激光雷达数据的深度学习目标检测方法大合集(下)

    作者 | 黄浴 来源 | 转载自知乎专栏自动驾驶的挑战和发展 [导读]在近日发布的<值得收藏!基于激光雷达数据的深度学习目标检测方法大合集(上)>一文中,作者介绍了一部分各大公司和机构基于 ...

最新文章

  1. window 获取进程运行长
  2. Clipper: 开源的基于图论框架的鲁棒点云数据关联方法(ICRA2021)
  3. python 反爬取数据
  4. 安卓开发网络资源汇总
  5. Rotation Rose各部分的名称
  6. 作者:蓝梦微, 女, 中国人民大学信息学院博士生,CCF学生会员。
  7. 数据结构之树与二叉树的应用:哈夫曼树(最优二叉树)
  8. matlab plot symbol,导入时出错matlab.引擎不导入ubuntu16.04上python3.5.2中的matplotlib。为什么?...
  9. ios 数字键盘左下角添加按钮_ios数字键盘添加完成按钮
  10. 3级城市选择(数据库版)
  11. Thingsboard 3.1.0 - 规则链:外部结点REST API
  12. 《深度学习Python实践》第22章——文本分类实例
  13. spearman相关性分析_数据的相关分析及SPSS算例
  14. h5唤起App两种方式 Schema Universal Link
  15. 2016年全球超级计算机榜首是,中国神威·太湖之光荣登全球超级计算机500强榜首...
  16. 概率论_证明_辛钦大数定律
  17. 微信小程序基础学习(2)- 模板与配置:WXML 模板语法、WXSS 模板样式、全局配置、页面配置、网络数据请求
  18. php微信授权ajax,ajax 实现微信网页授权登录
  19. 都在用DevOps,linux基础命令要是还没掌握就out了
  20. 利用JavaScript实现发表、修改、删除评论

热门文章

  1. 【力扣】数据结构入门【7天32题数据结构入门】
  2. 给你一份架构部操作手册,你会用么?
  3. 鸿蒙大陆罪恶深渊哪里出,罪恶深渊 - 音阙诗听 - 5SING中国原创音乐基地
  4. Oracle ORA-12154: TNS:could not resolve the connect identifier specified(不积跬步,无以至千里)
  5. Cannot assign requested address解决办法
  6. 丑小鸭到白天鹅的蜕变—棋牌游戏
  7. 基于opencv的面部特征交换(可选部位,可视化窗口)
  8. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.jt.mapper.UserM
  9. 彻底弄懂I420格式
  10. 一文彻底了解Hive