opencv2(2017.5.3)

1.cv::Mat有若干成員函數可以獲取圖像屬性,at(int y,int x)可以用來存取圖像元素,但是必須知道圖像數據類型!

例:


image.at<cv::Veb3b>(j,i)[channel]=value;//彩色圖像,其中channel注明了顏色通道號;```

類似的,open cv 還有二元,四元向量;

```cv::Mat_<uchar>im2=image;

im2(50,100)=0;//存取第50行,100列//重載了運算符()```

##2.使用指針遍歷圖像(使用雙重循環遍歷所有的像素值)

顏色縮減函數:

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++)//得到第j行的首地址

   {

        uchar* data=image.ptr<uchar>(j);//ptr可以得到任意行的首地址,此處返回第j行的首地址

        for(int i=0;i<nc;i++)

       {
          //處理每一個像素 
         data[i]=data[i]/div*div+div/2

       }//像素處理完成

   }//行處理完成

}```

主函數:


image=cv::imread("boldt.jpg");

//處理圖像(調用函數)

colorReduce(image);

//顯示圖像

cv::namedWindow("image");

cv::imshow("image",image);```

#3.使用迭代器遍歷彩色圖像

void colorReduce(cv::Mat &image,int div=64)

{

    cv::Mat_<cv::Vec3b>::iterator it=image.begin<cv::Vec3b>();//得到起始位置的迭代器

    cv::Mat_<cv::Veb3b>::iterator itend=image.end<cv::Veb3b>();//得到終止位置的迭代器

   for(;it!=itend;++it)

  {//處理每個像素

           (*)it[0]=(*)it[0]/div*div+div/2;

           (*)it[1]=(*)it[1]/div*div+div/2;

           (*)it[2]=(*)it[2]/div*div+div/2;

  }

} ```

4.使用卷積核進行濾波,編寫圖像銳化函數

void sharpen2D(const cv::Mat &image,cv::Mat &result)

{

       cv::Mat kernel(3,3,CV_32f,cv::Scalar(0));//構造核,所有的項初始化為0

       //對核元素賦值

       kernel.at<float>(1,1)=5.0;

       kernel.at<float>(1,0)=-1.0;

       kernel.at<float>(1,2)=-1.0;

       kernel.at<float>(0,1)=-1.0;

       kernel.at<float>(2,1)=-1.0;

//對圖像進行濾波

cv::filter2D(image,result,image.depth(),kernel);

}```

#5.進行簡單的圖像運算(此處僅針對兩個輸入圖像具有相同尺寸)

(1)加、減、乘、除        

cv::add(image1,w1,image2,w2,b,result) ——> open cv2 里面對運算符進行了重載,可以直接寫符號: result=0.7image1+0.9image2

cv::substract 、cv::absdiff、cv::multiply、cv::divide```

(2)位運算符

cv::bitwise_and、cv::bitwise_or 、cv::bitwise_xor 、cv::bitwise_not

(3)找矩陣最大最小值、矩陣的一些運算

cv::max、 cv::min、矩陣求逆m1.inv()、矩陣轉置m1.t()、矩陣的行列式m1.determinate()、向量模v1.norm()、向量叉乘v1.cross(v2)、向量點乘v1.cross(v2)

(4)只接受一個輸入的操作符

cv::sqrt、 cv::pow 、cv::abs 、cv::cuberoot 、cv::exp 、cv::log

6.對圖像的一個通道進行操作后,再合并

//創建一個圖像向量

std::vector<cv::Mat>planes;

//將一個三通道圖像分離成三個單通道圖像

cv::spirit(image,planes);```

//將新圖層疊加到藍色通道

planes[0]+=image2;

//將三個單通道圖像合并為一個三通道圖像

cv::merge(planes,result);```

7.定義感興趣區域ROI(此處針對兩張圖像具有不同大小尺寸,比如想在原圖像上加一個logo)

只要ROI大小和logo圖片大小一致,則可以調用cv::add;ROI位置決定了logo圖像被插入的位置;

//定義圖像ROI

cv::Mat imageROI;//ROI與他的父圖像指向同一塊內存緩沖區

imageROI=image(cv::Rect(385,270,logo.cols,logo.rows))或者imageROI=image(cv::Range(270,270+logo.rows),cv::Range(385,385+logo.cols))

//插入logo                                                                                          或    //加載掩模(必須是灰度圖)

cv::addWeighted(imageROI,1.0,logo,0.3,0.,imageROI)              cv::Mat mask=cv::imread("logo.bmp",0)   //此處0代表灰度圖像

                                                                                                         //通過掩模拷貝ROI

                                                                                                        logo.copyTo(imageROI,mask)```

8.類的設計

class ColorDetector{

private:

 int minDist;  //最小可接受距離

 cv::Vec3b  target;//目標色

 cv::Mat result;//結果圖像

 //構造函數

ColorDetector():minDist(100){

   target[0]=target[1]=target[2]=0; //初始化默認參數

}

//設置顏色距離閾值,閾值必須是正,否則設為0

void setColorDistanceThreshold(int distance){

 if(distance<0)   distance=0;

 minDist=distance;

}

//獲取顏色距離閾值

int getColorDistanceThreshold() const{

 return minDist;

}

//設置需檢測的顏色

void setTargetColor(unsigned char blue,unsigned char green,unsigned char red){

 target[0]=blue;    arget[1]=green;    target[2]=red;

}

//獲取需檢測的顏色

cv::Vec3b getTargetColor() const{

 return target;

}

cv::Mat ColorDetctor::process(const cv::Mat &image){

 result.create(image.rows,image.cols,CV_8U);//按需重新分配二值圖像,與輸入圖像的尺寸相同,但只有一個通道

//得到迭代器

cv::Mat_<cv::Vec3b>::const_iterator it=image.begin<cv::Vec3b>();

cv::Mat_<cv::Vec3b>::const_iterator itend=image.end<cv::Vec3b>();

cv::Mat_<unchar>::iterator itout=result.begin<unchar>();

//遍歷每個像素

for(;it!=itend;++it,++itout){

 if(getDistance(*it)<minDist)     *itout=255;

 else  *itout=0;

}

 return result;

}

//計算與目標顏色的距離

int getDistance(const cv::Vec3b& color)const{

 return abs(color[0]-target[0])+abs(color[1]-target[1])+abs(color[2]-target[2]);

}

}

int main(){

 //1.創建圖像處理對象

 ColorDetector cdetect;

 //2.讀取輸入圖像

 cv::Mat image=cv::imread("1.jpg");

 if(!image.data)

 return 0;

 //3.設置輸入參數

 cdetect.setTargetColor(130,190,230);//藍天的顏色

 cv::namedwindow("result");

 //4.處理并顯示結果

 cv::imshow("result",cdetect.process(image))

 cv::waitkey();

 return 0;

}```

9.控制器實現類之間的通信

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容