OpenCV常用函数

1. image.row().setTo()

快捷地设置某些行、列的值可以获取某行、列的图像再调用setTo()函数进行设置。
对于图像image:
image.row()返回cv::Mat,其通道数和image相同,宽高是(image.cols,1)
image.col()返回cv::Mat,其通道数和image相同,宽高是(1,image.rows)
image.setTo(cv::Scalar(255,255,0))image设为指定的值cv::Scalar(255,255,0)

#include 
#include 
#include 
int main()
{
	cv::Mat img = cv::imread("ALBT9701_.jpg", 1);
	for (int i = 0; i != 10; ++i)
	{
		img.row(i).setTo(cv::Scalar(0, 255, 255));
		img.col(i).setTo(cv::Scalar(0, 255, 255));
	}
	for (int i = img.rows-10; i != img.rows; ++i)
	{
		img.row(i).setTo(cv::Scalar(0, 255, 255));
	}
	for (int i = img.cols - 10; i != img.cols; ++i)
	{
		img.col(i).setTo(cv::Scalar(0, 255, 255));
	}
	cv::imshow("img", img);
	cv::waitKey(0);
}

效果如图1所示:

OpenCV常用函数_第1张图片
图1 image.row().setTo()

2. 图像运算

图像说白了就是普通的矩阵,可以进行加减乘除与或非等运算,再OpenCV中有相应的函数来完成这些操作,同时也重载了相应的运算符。
例如图像的加权相加:

#include 
#include 
#include 
int main()
{
	cv::Mat img1 = cv::imread("greed.jpg", 1);
	cv::Mat img2 = cv::imread("red.jpg", 1);
	cv::Mat img;
	/* 使用函数进行加权相加 */
	cv::addWeighted(img1, 1.0, img2, 1.0, 0., img, -1);
	/* 或者使用重载运算符进行加权相加 */
	// img = 1.0 * img1 + 1.0 * img2;
	cv::imshow("img", img);
	cv::waitKey(0);
}

其中greed.jpg:

OpenCV常用函数_第2张图片
图2 greed.jpg
red.jpg:
OpenCV常用函数_第3张图片
图3 red.jpg
加权相加的效果是:
OpenCV常用函数_第4张图片
图4 cv::addWeighted()-->yellow
还有许多其它的运算函数、重载的运算符。

3. cv::split()、cv::merge()

cv::split()实现通道分离、cv::merge()实现通道融合。

#include 
#include 
#include 
#include 

int main()
{
	cv::Mat img = cv::imread("ALBT9701_.jpg", 1);
	cv::imshow("img", img);

	std::vector<cv::Mat> planes;
	cv::split(img, planes);

	//cv::imshow("red-channel.jpg", planes[2]);
	//cv::imshow("green-channel.jpg", planes[1]);
	//cv::imshow("blue-channel.jpg", planes[0]);

	cv::Mat result;
	/* img与result的每个像素都是完全相同的 */
	cv::merge(planes, result);
	cv::imshow("result", result);
	
	/* 求img与result的差 */
	cv::Mat diff = img - result;
	for (int i = 0; i != img.rows;++i)
	{
		cv::Vec3b *ptr = diff.ptr<cv::Vec3b>(i);
		for (int j = 0; j != img.cols; ++j)
		{
		    /* 由于diff三个通道每个像素的灰度值都是0,因此不会进入if语句块 */
			if (ptr[j]!=cv::Vec3b(0,0,0))
			{
				std::cout << ptr[j] << std::endl;
			}
		}
	}

	cv::waitKey(0);
}

4. 比较颜色

构建简单的算法去除图像中某种特定颜色的像素。
代码如下:
RemoveColor.h

#pragma once

#include 

class RemoveColor
{
public:
	RemoveColor(cv::Vec3b target,int dist);
	~RemoveColor();
	void setTarget(cv::Vec3b target);
	cv::Vec3b getTarget();
	void setMaxDist(int max_dist);
	int getMaxDist();
	int calcuDist(cv::Vec3b color);
	cv::Mat process(cv::Mat img);
private:
	cv::Vec3b m_target;
	int m_max_dist;
};

RemoveColor.cpp

#include "RemoveColor.h"

RemoveColor::RemoveColor(cv::Vec3b target, int dist)
{
	this->m_max_dist = dist;
	this->m_target = target;
}

void RemoveColor::setTarget(cv::Vec3b target)
{
	this->m_target = target;
}
cv::Vec3b RemoveColor::getTarget()
{
	return this->m_target;
}
void RemoveColor::setMaxDist(int max_dist)
{
	this->m_max_dist = max_dist;
}
int RemoveColor::getMaxDist()
{
	return this->m_max_dist;
}
int RemoveColor::calcuDist(cv::Vec3b color)
{
	return (abs(this->m_target[0] - color[0]) + 
		abs(this->m_target[1] - color[1]) + 
		abs(this->m_target[2] - color[2]));
}
cv::Mat RemoveColor::process(cv::Mat img)
{
	cv::Mat result;
	result.create(img.size(), CV_8UC1);
	cv::Mat_<cv::Vec3b>::const_iterator itbeg = img.begin<cv::Vec3b>();
	cv::Mat_<cv::Vec3b>::const_iterator itend = img.end<cv::Vec3b>();
	cv::Mat_<uchar>::iterator it_result = result.begin<uchar>();
	/* 迭代器遍历img和result */
	for (auto it = itbeg; it != itend; ++it, ++it_result)
	{
		if (calcuDist(*it) <= m_max_dist)
		{
			*it_result = 0;
		}
		else
		{
			*it_result = ((*it)[0] + (*it)[1] + (*it)[2])/3;
		}
	}
	return result;
}

RemoveColor::~RemoveColor(){}

调用方法:

#include 
#include 
#include "RemoveColor.h"

int main()
{
	cv::Mat_<cv::Vec3b> img = cv::imread("ALBT9701_.jpg");
    /* 构造 */
	RemoveColor rc(cv::Vec3b(255,255,0),0);
	/* 处理 */
	cv::Mat result = rc.process(img);

	cv::imshow("result", result);
	cv::imshow("img", img);
	cv::waitKey(0);
}

上面int calcuDist(cv::Vec3b color);也可以用cv::absdiff()cv::sum()来实现。举例说明这两个函数的使用方法:

cv::Vec3b result;
cv::Vec3b color(1, 2, 3);
cv::Vec3b target(11, 22, 33);
cv::absdiff(color, target, result);  // result的结果是(10,20,30)
/* cv::sum()返回值是四维的,这里只需第一维 */
auto it = cv::sum(result)[0];        // it == 60

5. cv::floodFill()

cv::floodFill()可以查找指定像素颜色并将其设置为目标颜色,该函数会将指定的某个像素位置周围的连续区域都进行判断。例如:

#include 
#include 

int main()
{
	cv::Mat_<cv::Vec3b> img = cv::imread("ALBT9701__.jpg");

	cv::floodFill(img, cv::Point(550, 250), cv::Scalar(255, 0, 0), 
	(cv::Rect*)0, cv::Scalar(35, 35, 35), cv::Scalar(35, 35, 35), 
	cv::FLOODFILL_FIXED_RANGE);
	
	cv::imshow("img", img);
	cv::waitKey(0);
}

图5是输入图像,图6是处理后的效果。坐标(500,250)处于颜色(255,255,0)大矩形位置,可以看到整个大矩形被重置了颜色,而小矩形不变。

OpenCV常用函数_第5张图片
图5 输入图像
OpenCV常用函数_第6张图片
图6 效果

6. 行列式相乘[线性代数]

OpenCV中行列式相乘要求两个矩阵数据类型必须相同,且数据类型是CV_32FC1、 CV_64FC1、 CV_32FC2、 CV_64FC2之一。
相乘与顺序有关,这点与行列式乘法规则一样。ab与ba是完全不同的。

/* OpenCV行列式相乘,通道1*通道1 - 通道2*通道2 = 通道1
                    通道1*通道2 + 通道2*通道1 = 通道2*/
#include 
#include 
#include 
#include 
#include 

int main()
{
	cv::Mat a(2, 3, CV_32FC2);
	cv::Mat b(3, 2, CV_32FC2);
	cv::Mat img(2, 2, CV_32FC2);
	for (int i = 0; i != 2; ++i)
	{
		for (int j = 0; j != 3; ++j)
		{
			a.at<cv::Vec2f>(i, j) = cv::Vec2f(i + j, 1);
		}
	}
	int count = 0;
	for (int i = 0; i != 3; ++i)
	{
		for (int j = 0; j != 2; ++j)
		{
			b.at<cv::Vec2f>(i, j) = cv::Vec2f(++count, 1);
		}
	}
	img = a*b;

	cv::imshow("img", img);
	cv::waitKey(0);

	return 0;
}

图7是相乘结果示意图:

OpenCV常用函数_第7张图片
图7 行列式相乘

你可能感兴趣的:(OpenCV)