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.控制器实现类之间的通信

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容