opencv 邊緣檢測,角點檢測

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




}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章