opencv4 学习 04 掩码操作和图像混合
1.掩码操作
对图片每个像素做如下变换:
p[i,j] = 5*p[i,j] - p[i,j-1] - p[i,j+1] - p[i-1,j] - p[i+1,j]
p[i,j] 表示当前像素。
首先手动实现一个该函数,代码如 sharpen 函数,然后和opencv内置的filter2D函数做比较。
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; void sharpen(const Mat& myImage, Mat& Result) { CV_Assert(myImage.depth()==CV_8U); const int nchannels = myImage.channels(); Result.create(myImage.size(),myImage.type()); for(int j=1; j<myImage.rows-1;++j) { const uchar* previous = myImage.ptr<uchar>(j-1); const uchar* current = myImage.ptr<uchar>(j); const uchar* next = myImage.ptr<uchar>(j+1); uchar* output = Result.ptr<uchar>(j); for(int i=nchannels;i<(myImage.cols-1)*nchannels;++i) { *output++ = saturate_cast<uchar>(5*current[i] - current[i-nchannels] - current[i+nchannels] - previous[i] - next[i]); } } Result.row(0).setTo(Scalar(0)); Result.row(Result.rows-1).setTo(Scalar(0)); Result.col(0).setTo(Scalar(0)); Result.col(Result.cols-1).setTo(Scalar(0)); } int main(int argc, char* argv[]) { Mat src, dst0, dst1; string filename = "lena.jpg"; src = imread(filename, IMREAD_COLOR); namedWindow("Input", WINDOW_AUTOSIZE); namedWindow("Output", WINDOW_AUTOSIZE); imshow("Input", src); double t = (double)getTickCount(); sharpen(src,dst0); t = ((double)getTickCount() - t)/getTickFrequency(); cout << "Hand written function time passed in seconds: " << t << endl; imshow("Output", dst0); waitKey(); // Built-in function Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); t = (double)getTickCount(); filter2D(src, dst1, src.depth(), kernel); t = ((double)getTickCount()-t)/getTickFrequency(); cout << "Built-in filter2D time passed in seconds: " << t << endl; imshow("Output", dst1); waitKey(); return 0; }
耗时如下:
Hand written function time passed in seconds: 0.00977115
Built-in filter2D time passed in seconds: 0.00188034
2.图像混合
addWeighted() 函数的使用
int main(int argc, char* argv[]) { double alpha = 0.5; double beta = 1 - alpha; Mat src1, src2, dst; src1 = imread("LinuxLogo.jpg"); src2 = imread("WindowsLogo.jpg"); // dst = src1*alpha + src2*beta + gamma addWeighted(src1, alpha, src2. beta, 0.0, dst); imshow("Linear Blend", dst); waitKey(0); return 0; }
参考:
https://docs.opencv.org/3.4/d7/d37/tutorial_mat_mask_operations.html
https://docs.opencv.org/3.4/d5/dc4/tutorial_adding_images.html