#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

class ColorDetector{
private:
//最小可接受距离
int minDist;
//目标色
cv::Vec3b target;
//结果图像
cv::Mat result;
//空的构造函数
public:
ColorDetector():minDist(100){
//初始化默认值
//minDist=100;
target[0]=target[1]=target[2]=0;
}

void setColorDistanceThreshod(int distance){
if(distance<0)
distance=0;
minDist=distance;
}
int getColorDistanceThreshod(){
return minDist;
}
//设置需检测的颜色
void setTargetColor(unsigned char red,
unsigned char green,
unsigned char blue){
//注意顺序
target[0]=blue;target[1]=green;target[2]=red;
}
void setTargetColor(cv::Vec3b color){
target=color;
}
cv::Vec3b getTargetColor(){
return target;
}
//两个函数 一个distance 一个 process
cv::Mat process( cv::Mat &image);
int getDistance(const cv::Vec3b& color)const{
return abs(color[0]-target[0])+abs(color[1]-target[1])+abs(color[0]-target[0])+
abs(color[2]-target[2]);

}

};
//int ColorDetector::getDistance(const cv::Vec3b& color)const{
// return abs(color[0]-target[0])+abs(color[1]-target[1])+abs(color[0]-target[0])+
// abs(color[2]-target[2]);
//
//}

cv::Mat ColorDetector::process(cv::Mat &image){
//按需重新分配二指图像 与输入图像的尺寸相同,但是只有一个通道
result.create(image.rows,image.cols,CV_8U);
//循环处理过程
cv::Mat_<cv::Vec3b>::iterator it=image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend=image.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator itout;itout=result.begin<uchar>();
//处理每个像素,对result复制。
for (;it!=itend;it++,itout++)
{
if (getDistance(*it)<minDist)
{
*itout=255;

else
{
*itout=0;
}
}
return result;
}
class Histto1D
{

private:
int histSize[1];
float hranges[2];
const float* range[1];
int channels[1];
public:
Histto1D(){
histSize[0]=256;
hranges[0]=0.0;
hranges[1]=255.0;
range[0]=hranges;
channels[0]=0;
}
cv::MatND getHist(const cv::Mat &img);
cv::Mat getHistImage(const cv::Mat &img);

};
cv::MatND Histto1D::getHist(const cv::Mat &img){
cv::MatND hist;
cv::calcHist(&img,1,
channels,
cv::Mat(),
hist,
1,
histSize,
range);
return hist;
//calcHist( const Mat* images, int nimages,
//const int* channels, InputArray mask,
//OutputArray hist, int dims, const int* histSize,
//const float** ranges, bool uniform=true, bool accumulate=false );
}
cv::Mat Histto1D::getHistImage(const cv::Mat &img){
cv::MatND hist=getHist(img);
double minVal,maxVal;
cv::minMaxLoc(hist,&minVal,&maxVal,0,0);
//显示直方图的图像
cv::Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255));
//设置一个最高点
int hpt=static_cast<int>(0.9*histSize[0]);
//每个条目绘制一条直线
for (int h=0;h<histSize[0];h++)
{
float binVal=hist.at<float>(h);
int intensity=static_cast<int>(binVal*hpt/maxVal);
//画直线的干活
cv::line(histImg,cv::Point(h,histSize[0]),cv::Point(h,histSize[0]-intensity),cv::Scalar(0));

}
return histImg;

}
//

void colorReduce(cv::Mat &image,int div=64){
int n1=image.rows;
int nc=image.cols*image.channels();
for (int j=0;j<n1;j++)
{
uchar* data=image.ptr<uchar>(j);
for (int i=0;i<nc;i++)
{
data[i]=data[i]/div*div+div/2;
}
}
}

class MorphoFeature{
private:
//用于生成二值图像的阈值
int threshold;
//角点检测中用到的结构元素
cv::Mat cross;
cv::Mat diamond;
cv::Mat square;
cv::Mat x;
public:
MorphoFeature();
void applyThreshold(cv::Mat& result);
cv::Mat getEdge(const cv::Mat &image);
cv::Mat getCorner(const cv::Mat &image);
void drawCorner(const cv::Mat& bin,cv::Mat& image){ //std<<cout<<bin.

cv::Mat_<uchar>::const_iterator it=bin.begin<uchar>();

cv::Mat_<uchar>::const_iterator itend=bin.end<uchar>();
int i=0;
for (i;it!=itend;i++,it++)
{
if(!*it)
cv::circle(image,cv::Point(i%image.step,i/image.step),5,cv::Scalar(255,0,0));
}
}

};
MorphoFeature::MorphoFeature():threshold(40),
cross(5,5,CV_8U,cv::Scalar(0)),
diamond(5,5,CV_8U,cv::Scalar(1)),
square(5,5,CV_8U,cv::Scalar(1)),
x(5,5,CV_8U,cv::Scalar(0)){
for (int i=0;i<5;i++)
{
cross.at<uchar>(2,i)=1;
cross.at<uchar>(i,2)=1;
}
diamond.at<uchar>(0,0)=0;
diamond.at<uchar>(0,1)=0;
diamond.at<uchar>(1,0)=0;
diamond.at<uchar>(4,4)=0;
diamond.at<uchar>(3,4)=0;
diamond.at<uchar>(4,3)=0;
diamond.at<uchar>(4,0)=0;
diamond.at<uchar>(0,4)=0;
diamond.at<uchar>(3,0)=0;
diamond.at<uchar>(0,3)=0;
diamond.at<uchar>(4,1)=0;
diamond.at<uchar>(1,4)=0;

for (int i=0;i<5;i++)
{
x.at<uchar>(i,i)=0;
x.at<uchar>(4-i,i)=0;
}
}
void MorphoFeature::applyThreshold(cv::Mat& result){
//
if (threshold>0)
{
cv::threshold(result,result,threshold,255,CV_THRESH_BINARY);
}
}
cv::Mat MorphoFeature::getEdge(const cv::Mat &image){
cv::Mat result;
cv::morphologyEx(image,result,cv::MORPH_GRADIENT,cv::Mat());
applyThreshold(result);
return result;

}
cv::Mat MorphoFeature::getCorner(const cv::Mat &image){
cv::Mat result;
cv::dilate(image,result,cross);
cv::erode(result,result,diamond);
cv::Mat result2;
cv::dilate(image,result2,x);
cv::erode(result2,result2,square);
//
cv::absdiff(result2,result,result);
applyThreshold(result);
//cv::cvtColor(result,result,CV_BGR2GRAY);
return result;
}

int main(){
//创建图像处理对象
ColorDetector cdetect;
cv::Mat gray,img =cv::imread("F:\\C++\\myfirstopencvapp\\images\\building.jpg"),img2;
img2=cv::imread("D:\\Image\\0\\0_9_9990.jpg",0);
//cv::namedWindow("img my");
if (!img.data)
{
std::cout<<"guoliang"<<img.size().height<<img.size().width;
return -1;
}
//cv::imshow("img my",img2);

cdetect.setTargetColor(130,190,230);
//cv::namedWindow("result");
//cv::imshow("result",cdetect.process(img));
cv::cvtColor(img,gray,CV_BGR2GRAY);
//cv::namedWindow("gray");
//cv::imshow("gray",gray);
std::cout<<"gray test"<<std::endl;
std::cout<<(int)gray.at<uchar>(10,0)<<std::endl;
std::cout<<"gray test"<<std::endl;
//cv::MatND hist;
//float range[2]={0.0,255.0};

//cv::calcHist(gray,1,hist,256,range);
Histto1D my;
cv::MatND histgray=my.getHist(img2);
for (int i=0;i<256;i++)
{
std::cout<<i<<"====="<<histgray.at<float>(i)<<std::endl;

}
cv::namedWindow("histimg");
cv::imshow("histimg",my.getHistImage(img2));

cv::Mat threshold;
cv::threshold(gray,threshold,55,255,0);
cv::namedWindow("binary");
cv::imshow("binary",threshold);
cv::Mat result;
cv::equalizeHist(gray,result);
cv::namedWindow("lut");
cv::imshow("lut",result);
cv::Mat imgROI=img;//cv::Rect(110,260,35,40)
int minsat=65;
//colorhi
cv::Mat img3f;
//img.convertTo(img, CV_32FC3, 1.0/255);
cv::namedWindow("img3f");
cv::imshow("img3f",img);
//colorreduce

cv::namedWindow("img2");
cv::imshow("img2",img2);
//std::cout<<(int)img.at<uchar>(5,2);
std::cout<<"img2:"<<std::endl<<img2(cv::Rect(200,150,10,10))<<std::endl;
colorReduce(img2,32);
cv::namedWindow("reduce");
cv::imshow("reduce",img2);
std::cout<<"reduce:"<<std::endl<<img2(cv::Rect(200,150,10,10))<<std::endl;
//
cv::Mat element1(3,3,CV_8U,cv::Scalar(1));
cv::Mat erode,dilate;
cv::erode(threshold,erode,element1);
cv::namedWindow("erode");
cv::imshow("erode",erode);
cv::dilate(threshold,dilate,element1);
cv::namedWindow("dilate");
cv::imshow("dilate",dilate);
//比较腐蚀两次的效果和 膨胀结构元素后再去腐蚀图像。
cv::Mat erode2;
cv::erode(threshold,erode2,element1,cv::Point(-1,-1),2);
cv::namedWindow("erode2");
cv::imshow("erode2",erode2);
cv::Mat element2;
cv::dilate(element1,element2,element1);
std::cout<<element1<<std::endl<<"element2:"<<std::endl<<element2;

cv::Mat eledilerode;
cv::erode(threshold,eledilerode,element2);
cv::namedWindow("eledilerode");
cv::imshow("eledilerode",eledilerode);

cv::Mat element3(5,5,CV_8U,cv::Scalar(1));
cv::Mat close,open,closeopen,openclose;
cv::morphologyEx(threshold,close,cv::MORPH_CLOSE,element3);
cv::namedWindow("close");
cv::imshow("close",close);
cv::morphologyEx(close,closeopen,cv::MORPH_OPEN,element3);
cv::namedWindow("closeopen");
cv::imshow("closeopen",closeopen);
cv::morphologyEx(threshold,open,cv::MORPH_OPEN,element3);
cv::namedWindow("open");
cv::imshow("open",open);
cv::morphologyEx(open,openclose,cv::MORPH_OPEN,element3);
cv::namedWindow("openclose");
cv::imshow("openclose",openclose);

//进行边缘和角点检测
MorphoFeature morpho;
cv::cvtColor(img,img,CV_BGR2GRAY);
cv::Mat edge;
edge=morpho.getEdge(img);
cv::namedWindow("edge");
cv::imshow("edge",edge);
cv::Mat corn;
corn=morpho.getCorner(img);
//cv::Mat_<cv::Vec3b>::const_iterator uit=img.begin<cv::Vec3b>();
//cv::MatConstIterator_<cv::Vec3b>it=corn.begin<cv::Vec3b>();
morpho.drawCorner(corn,img);
cv::namedWindow("corn");
cv::imshow("corn",corn);
cv::namedWindow("corn and img");
cv::imshow("corn and img",img);

//
cv::waitKey(0);
return 'd';

}

opencv 边缘检测,角点检测相关推荐

  1. MFC+OPENCV实现角点检测

    MFC+OPENCV实现角点检测: // 角点检测 // 根据<基于OpenCV的计算机视觉技术实现>#define max_corners 200; // 限定的最大角点数IplImag ...

  2. OpenCV ChArUco角的检测

    OpenCV ChArUco角的检测 ChArUco角的检测 目标 源代码 ChArUco Board创建 ChArUco板检测 拍摄输入图像 读取相机校准参数(仅用于相机校准检测) 检测标记 ChA ...

  3. 【opencv】角点检测——虚线表格

    [opencv]角点检测--虚线表格 处理对象--虚线表格 处理方法--角点检测 Harris角点检测 函数解读 处理结果 处理对象--虚线表格 把之前做研电赛的东西做一点小的分享,先给大家看一下所处 ...

  4. Opencv java 角点检测 preCornerDetect(15)

    之前我们讲过一节的角点检测,是用的cornerHarris 这个方法,今天我们介绍另外的一种方法preCornerDetect 进行角点检测 效果 首先我们看一下角点检测的效果: 代码 那么代码上应该 ...

  5. OpenCV Fast角点检测

    FAST是一种用于角点检测的算法,该算法的原理是取图像中检测点,以改点为圆心的周围邻域内像素点判断监测点是否为角点. OpenCV中的FAST检测算法是用传统方法实现的. 实例化fast fast = ...

  6. opencv 实现角点检测 Shi-Tomasi角点检测

    角点检测概述 角点检测概述 Harris角点检测算法手动实现 Harris角点检测算法手动实现 opencv中使用Harris角点检测 opencv中使用Harris角点检测 opencv中使用 Sh ...

  7. OpenCV实现角点检测(cornerHarris)

    1.概述 案例:使用cornerHarris实现角点检测,并调节其参数看看不同参数下的不同效果 技术:Qt+C+++OpenCV 角点检测函数介绍: cornerHarris(src,dst,bloc ...

  8. opencv harris 角点检测

    一.图像特征的分类 [OpenCV入门教程之十六]OpenCV角点检测之Harris角点检测_[浅墨的游戏编程Blog]毛星云(浅墨)的专栏-CSDN博客_基于轮廓曲线的角点检测 下面部分图像来自与B ...

  9. opencv棋盘格角点检测原理总结

    第一步,局部平均自适应阈值化方法对亮度不均匀情况适应性强,因此用该方法对图像二值化,均衡化后得到了理想的门限,效果如图2所示. 第二步,图像膨胀分离各个黑块四边形的衔接,由于膨胀的是白色像素点,因此能 ...

  10. OpenCV中角点检测:Harris、Shi-Tomasi、亚像素级角点检测

    1.角点的定义 角点通常被定义为两条边的交点,或者说,角点的局部邻域应该具有两个不同区域的不同方向的边界.比如,三角形有三个角,矩形有四个角,这些就是角点,也是他们叫做矩形.三角形的特征. 角点是个很 ...

最新文章

  1. MySQL面试题 | 附答案解析(六)
  2. Python手动编程实现斐波那契数列
  3. 重磅!苹果祭出大招:史上最强 Mac 发布,iPad OS 惊艳问世
  4. js正则验证特殊字符
  5. java == equals_java中==与equals
  6. 初学者用涩性胶皮好还是粘性_乒乓球胶皮的保养方法
  7. cat命令分析_学习记录
  8. delphi中的提前声明
  9. 闲聊位置之 POI数据
  10. SAP Spartacus RouteEvent,如何从localhost跳转到其他路由路径的
  11. windows下的gvim配置
  12. 企业开发需要的git提交和拉取代码(本地仓库和github演示)
  13. 前端技巧之苹果官网效果分析
  14. 【ubuntu】安装qemu
  15. 【概率论】3-4:二维分布(Bivariate Distribution)
  16. 疫情肆虐之下,阿里巴巴的攻与防!
  17. 音乐播放器 EasyMusic (一)
  18. android ps icon图标制作,PS设计App图标教程
  19. beta阶段测试基本概况对应机型硬件信息
  20. 8.6 百度首页编写-导航栏

热门文章

  1. 计算机许可管理器服务器名称是什么意思,部署 - 安装后的许可证服务器是什么?...
  2. kudu教程(一)——简介
  3. 并查集算法 | Union-Find Algorithm
  4. 在数据库中如何新增一个字段?
  5. 在番看付费美女直播,不想花钱,我这样做了!
  6. [网赚项目] 分享一个刚需赚钱项目,可多重变现,月入好几个w
  7. Win10搭建ELK8.0.0环境
  8. 微信原生小程序电商实战项目----附源码和分析
  9. -eq、-ne、-gt、-ge、-lt、-le英文意思
  10. Queue.queue 退出与阻塞