opencv 边缘检测,角点检测

#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';




}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值