我是靠谱客的博主 大气柜子,最近开发中收集的这篇文章主要介绍利用OpenCV实现对图像指定区域卷积,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

        OpenCV中的卷积函数filter2d()只能对整张图像进行卷积而无法对图像中的某一区域进行卷积。本文提供了利用OpenCV实现对图像指定区域卷积的函数(仅限单通道8位图)。

        函数如下:

bool ConvolvePartRegionOfImage(uchar* const pImage, const int imageWidth, const int imageHeight, const int regionX, const int regionY, const int regionWidth, const int regionHeight, Mat kernel)
{
	//参数保护
	if (regionX + regionWidth > imageWidth || regionY + regionHeight > imageHeight)return false;
	if (pImage == nullptr)return false;

	//提取感兴趣区域
	Mat image(imageHeight, imageWidth,  CV_8UC1, pImage);
	Mat img2(image, Rect(regionX, regionY, regionWidth, regionHeight));
	Mat img3 = img2.clone();

	//对感兴趣区域进行卷积
	filter2D(img3, img2, -1, kernel);

	return true;
}

        参数详情:

bool ConvolvePartRegionOfImage
(
uchar* const pImage,    //图像数据首地址
const int imageWidth,   //图像宽度
const int imageHeight,  //图像高度
const int regionX,      //指定区域的坐标x值
const int regionY,      //指定区域的坐标y值
const int regionWidth,  //指定区域宽度
const int regionHeight, //指定区域高度
Mat kernel;             //使用的卷积核
)

        测试用例:

#include<iostream>
#include"./opencv/include/opencv2/highgui.hpp"
#include"./opencv/include/opencv2/opencv.hpp"

using namespace std;
using namespace cv;

bool ConvolvePartRegionOfImage(uchar* const pImage, const int imageWidth, const int imageHeight, const int regionX, const int regionY, const int regionWidth, const int regionHeight, Mat kernel)
{
	//参数保护
	if (regionX + regionWidth > imageWidth || regionY + regionHeight > imageHeight)return false;
	if (pImage == nullptr)return false;

	//提取感兴趣区域
	Mat image(imageHeight, imageWidth, CV_8UC1, pImage);
	Mat img2(image, Rect(regionX, regionY, regionWidth, regionHeight));
	Mat img3 = img2.clone();

	//对感兴趣区域进行卷积
	filter2D(img3, img2, -1, kernel);

	return true;
}

int main()
{
	//读取图像并获取图像地址
	Mat image = imread("./bmp/1.bmp", -1);
	uchar* p = image.ptr<uchar>(0);

	//创建大小为3x3的十字交叉型卷积核
	Mat kernel = getStructuringElement(MORPH_CROSS, Size(3, 3));

	//调用函数
	ConvolvePartRegionOfImage(p, image.cols, image.rows, 10, 10, 50, 50, kernel);

	imshow("卷积后图像", image);
	waitKey(0);
	return 0;
}

        输出结果:

        原图像

       卷积后图像

         可以看到,图像中的部分区域进行了卷积,其余区域不变。

        不难发现,函数中原本可以对img2直接进行卷积,但实际上函数对图像多使用了一次Clone()函数得到img3进行操作,再将img3赋回img2

        从逻辑上这是多此一举的操作,但在实际测试中发现,如果不将图像复制出来卷积再赋值回去,在卷积核的尺寸>11的时候,图像的卷积无法生效,原因不明。
        所以为了稳定起见,函数内多使用了一次复制操作。


        以上函数只能实现图像单个区域的卷积,为了能够同时对图像多个区域进行卷积,提供重载函数如下:

bool ConvolvePartRegionOfImage(uchar* const pImage, const int imageWidth, const int imageHeight, vector<vector<int>> regionXYWH, Mat kernel)
{
	//参数保护
	if (pImage == nullptr)return false;
	if (regionXYWH[0].size() != 4)return false;

	Mat image(imageHeight, imageWidth, CV_8UC1, pImage);
	for (int i = 0; i < regionXYWH.size(); i++)
	{
		if (regionXYWH[i][0] + regionXYWH[i][2] > imageWidth || regionXYWH[i][1] + regionXYWH[i][3] > imageHeight)return false;
		Mat img2(image, Rect(regionXYWH[i][0], regionXYWH[i][1], regionXYWH[i][2], regionXYWH[i][3]));
		Mat img3 = img2.clone();

		//对感兴趣区域进行卷积
		filter2D(img3, img2, -1, kernel);
	}
	return true;
}

         参数详情:

bool ConvolvePartRegionOfImage
(
uchar* const pImage,    //图像数据首地址
const int imageWidth,   //图像宽度
const int imageHeight,  //图像高度
vector<vector<int>> regionXYWH,     //二维向量,指定区域{x坐标,y坐标,宽度,高度}
Mat kernel              //使用的卷积核
)

        谢谢观看!

最后

以上就是大气柜子为你收集整理的利用OpenCV实现对图像指定区域卷积的全部内容,希望文章能够帮你解决利用OpenCV实现对图像指定区域卷积所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部