Reputation: 680
I am new to Opencv C++. I am trying to convolve a mask with an image. For this I want to create my own mask so that I can use the filter2D array function to convolve my mask with the image. The mask which I want to create is:
char mask [3][3]= {{-1,0,1},{-1,0,1},{-1,0,1}};
For this I have tried the code below(to generate this mask):-
Mat kernel(3,3, CV_8UC1, Scalar(-1,0,1));
i have printed the mask values as
std::cout << kernel;
but the answer which I am getting is 0, 0, 0; 0, 0, 0; 0, 0, 0
I am expecting the answer to be -1, 0, 1; -1, 0, 1; -1, 0, 1
I know I am making a mistake in writing the channels properly. Can anyone help me understand what does the channel(CV_8UC1.... ) means and how to correct it and get the proper output.
Upvotes: 4
Views: 694
Reputation: 18341
You want to create a kernel
with negative
element for filter2D
, then you should't use the data type of CV_8UC1
. There is no negative value in unsigned type
.
And Mat kernel(3,3, CV_8UC1, Scalar(-1,0,1));
means create a signal- channel-unsigned-char kernel. You set Scalar(-1,0,1)
to kernel
, then only the first element(that is double -1)
is used, while saturate_cast<unchar>(-1) = 0
.
Generally, use CV_32FC1
instead.
For example:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(){
float mask[9] = {-1,0,1, -1, 0, 1, -1,0,1};
Mat kernel(3,3, CV_32FC1);
memcpy(kernel.data, mask, sizeof(float)*9);
cout << kernel<<endl;
}
The result:
[-1, 0, 1;
-1, 0, 1;
-1, 0, 1]
A similar question:
How to create cv::Mat from buffer (array of T* data) using a template function?
Upvotes: 1
Reputation: 1978
CV_8UC1 means 1 channel, 8 bit, uchar image.
Scalar is used to set the value of each channel, not each pixel/coordinate.
Ex 1:
Mat kernel(3,3, CV_8UC1, Scalar::all(0))
would mean creating a 3X3 matrix with 0s and since it is of type CV_8UC1, you can mention only one value, in this case 0.
EX 2:
Mat kernel(3,3, CV_8UC3, Scalar(0,0,255))
means creating a 3X3 matrix with 3 channels since the type is CV_8UC3 and setting channel 1 to 0, channel 2 to 0, channel 3 to 255.
Hence for your purpose to set row values, you cannot use scalar. Instead do this:
Mat C = (Mat_<double>(3,3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
Check this for more information.
Hope this helps!
Upvotes: 3