mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 09:25:45 +08:00
Tutorial Mask Operations on Matrices
This commit is contained in:
parent
954e2f9b9c
commit
45afd29b72
@ -28,24 +28,39 @@ the zero-zero index) on the pixel you want to calculate and sum up the pixel val
|
||||
the overlapped matrix values. It's the same thing, however in case of large matrices the latter
|
||||
notation is a lot easier to look over.
|
||||
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
Now let us see how we can make this happen by using the basic pixel access method or by using the
|
||||
@ref cv::filter2D function.
|
||||
You can download this source code from [here
|
||||
](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp) or look in the
|
||||
OpenCV source code libraries sample directory at
|
||||
`samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp`.
|
||||
@include samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
Now let us see how we can make this happen by using the basic pixel access method or by using the
|
||||
**Imgproc.filter2D()** function.
|
||||
You can download this source code from [here
|
||||
](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java) or look in the
|
||||
OpenCV source code libraries sample directory at
|
||||
`samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java`.
|
||||
@include samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
Now let us see how we can make this happen by using the basic pixel access method or by using the
|
||||
**cv2.filter2D()** function.
|
||||
You can download this source code from [here
|
||||
](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py) or look in the
|
||||
OpenCV source code libraries sample directory at
|
||||
`samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py`.
|
||||
@include samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py
|
||||
@end_toggle
|
||||
|
||||
The Basic Method
|
||||
----------------
|
||||
|
||||
Now let us see how we can make this happen by using the basic pixel access method or by using the
|
||||
**filter2D()** function.
|
||||
|
||||
Here's a function that will do this:
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp basic_method
|
||||
@ -132,37 +147,38 @@ The filter2D function
|
||||
Applying such filters are so common in image processing that in OpenCV there exist a function that
|
||||
will take care of applying the mask (also called a kernel in some places). For this you first need
|
||||
to define an object that holds the mask:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp kern
|
||||
|
||||
Then call the @ref cv::filter2D function specifying the input, the output image and the kernel to
|
||||
use:
|
||||
@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp filter2D
|
||||
|
||||
The function even has a fifth optional argument to specify the center of the kernel, a sixth
|
||||
for adding an optional value to the filtered pixels before storing them in K and a seventh one
|
||||
for determining what to do in the regions where the operation is undefined (borders).
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java kern
|
||||
|
||||
Then call the **Imgproc.filter2D()** function specifying the input, the output image and the kernel to
|
||||
use:
|
||||
@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java filter2D
|
||||
The function even has a fifth optional argument to specify the center of the kernel, a sixth
|
||||
for adding an optional value to the filtered pixels before storing them in K and a seventh one
|
||||
for determining what to do in the regions where the operation is undefined (borders).
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py kern
|
||||
@end_toggle
|
||||
|
||||
Then call the **cv2.filter2D()** function specifying the input, the output image and the kernell to
|
||||
Then call the **filter2D()** function specifying the input, the output image and the kernel to
|
||||
use:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp filter2D
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java filter2D
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py filter2D
|
||||
@end_toggle
|
||||
|
||||
The function even has a fifth optional argument to specify the center of the kernel, a sixth
|
||||
for adding an optional value to the filtered pixels before storing them in K and a seventh one
|
||||
for determining what to do in the regions where the operation is undefined (borders).
|
||||
|
||||
This function is shorter, less verbose and, because there are some optimizations, it is usually faster
|
||||
than the *hand-coded method*. For example in my test while the second one took only 13
|
||||
milliseconds the first took around 31 milliseconds. Quite some difference.
|
||||
@ -172,22 +188,7 @@ For example:
|
||||

|
||||
|
||||
@add_toggle_cpp
|
||||
You can download this source code from [here
|
||||
](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp) or look in the
|
||||
OpenCV source code libraries sample directory at
|
||||
`samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp`.
|
||||
|
||||
Check out an instance of running the program on our [YouTube
|
||||
channel](http://www.youtube.com/watch?v=7PF1tAU9se4) .
|
||||
@youtube{7PF1tAU9se4}
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
You can look in the OpenCV source code libraries sample directory at
|
||||
`samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java`.
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
You can look in the OpenCV source code libraries sample directory at
|
||||
`samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py`.
|
||||
@end_toggle
|
||||
|
@ -2,14 +2,10 @@ import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
|
||||
class MatMaskOperationsRun {
|
||||
|
||||
public void run(String[] args) {
|
||||
@ -31,8 +27,10 @@ class MatMaskOperationsRun {
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
Image img = toBufferedImage(src);
|
||||
displayImage("Input", img, 0, 200);
|
||||
HighGui.namedWindow("Input", HighGui.WINDOW_AUTOSIZE);
|
||||
HighGui.namedWindow("Output", HighGui.WINDOW_AUTOSIZE);
|
||||
|
||||
HighGui.imshow( "Input", src );
|
||||
double t = System.currentTimeMillis();
|
||||
|
||||
Mat dst0 = sharpen(src, new Mat());
|
||||
@ -40,8 +38,9 @@ class MatMaskOperationsRun {
|
||||
t = ((double) System.currentTimeMillis() - t) / 1000;
|
||||
System.out.println("Hand written function time passed in seconds: " + t);
|
||||
|
||||
Image img2 = toBufferedImage(dst0);
|
||||
displayImage("Output", img2, 400, 400);
|
||||
HighGui.imshow( "Output", dst0 );
|
||||
HighGui.moveWindow("Output", 400, 400);
|
||||
HighGui.waitKey();
|
||||
|
||||
//![kern]
|
||||
Mat kern = new Mat(3, 3, CvType.CV_8S);
|
||||
@ -58,8 +57,10 @@ class MatMaskOperationsRun {
|
||||
t = ((double) System.currentTimeMillis() - t) / 1000;
|
||||
System.out.println("Built-in filter2D time passed in seconds: " + t);
|
||||
|
||||
Image img3 = toBufferedImage(dst1);
|
||||
displayImage("Output", img3, 800, 400);
|
||||
HighGui.imshow( "Output", dst1 );
|
||||
|
||||
HighGui.waitKey();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
//! [basic_method]
|
||||
@ -108,38 +109,12 @@ class MatMaskOperationsRun {
|
||||
return Result;
|
||||
}
|
||||
//! [basic_method]
|
||||
|
||||
public Image toBufferedImage(Mat m) {
|
||||
int type = BufferedImage.TYPE_BYTE_GRAY;
|
||||
if (m.channels() > 1) {
|
||||
type = BufferedImage.TYPE_3BYTE_BGR;
|
||||
}
|
||||
int bufferSize = m.channels() * m.cols() * m.rows();
|
||||
byte[] b = new byte[bufferSize];
|
||||
m.get(0, 0, b); // get all the pixels
|
||||
BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
|
||||
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
|
||||
System.arraycopy(b, 0, targetPixels, 0, b.length);
|
||||
return image;
|
||||
}
|
||||
|
||||
public void displayImage(String title, Image img, int x, int y) {
|
||||
ImageIcon icon = new ImageIcon(img);
|
||||
JFrame frame = new JFrame(title);
|
||||
JLabel lbl = new JLabel(icon);
|
||||
frame.add(lbl);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.pack();
|
||||
frame.setLocation(x, y);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public class MatMaskOperations {
|
||||
public static void main(String[] args) {
|
||||
// Load the native library.
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
|
||||
new MatMaskOperationsRun().run(args); // run code
|
||||
new MatMaskOperationsRun().run(args);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
import cv2
|
||||
|
||||
|
||||
## [basic_method]
|
||||
def is_grayscale(my_image):
|
||||
return len(my_image.shape) < 3
|
||||
@ -26,7 +27,6 @@ def sharpen(my_image):
|
||||
height, width, n_channels = my_image.shape
|
||||
|
||||
result = np.zeros(my_image.shape, my_image.dtype)
|
||||
|
||||
## [basic_method_loop]
|
||||
for j in range(1, height - 1):
|
||||
for i in range(1, width - 1):
|
||||
@ -36,17 +36,16 @@ def sharpen(my_image):
|
||||
result[j, i] = saturated(sum_value)
|
||||
else:
|
||||
for k in range(0, n_channels):
|
||||
sum_value = 5 * my_image[j, i, k] - my_image[j + 1, i, k] - my_image[j - 1, i, k] \
|
||||
- my_image[j, i + 1, k] - my_image[j, i - 1, k]
|
||||
sum_value = 5 * my_image[j, i, k] - my_image[j + 1, i, k] \
|
||||
- my_image[j - 1, i, k] - my_image[j, i + 1, k]\
|
||||
- my_image[j, i - 1, k]
|
||||
result[j, i, k] = saturated(sum_value)
|
||||
## [basic_method_loop]
|
||||
|
||||
return result
|
||||
## [basic_method]
|
||||
|
||||
|
||||
def main(argv):
|
||||
filename = "../data/lena.jpg"
|
||||
filename = "../../../../data/lena.jpg"
|
||||
|
||||
img_codec = cv2.IMREAD_COLOR
|
||||
if argv:
|
||||
@ -57,8 +56,9 @@ def main(argv):
|
||||
src = cv2.imread(filename, img_codec)
|
||||
|
||||
if src is None:
|
||||
print "Can't open image [" + filename + "]"
|
||||
print "Usage:\nmat_mask_operations.py [image_path -- default ../data/lena.jpg] [G -- grayscale]"
|
||||
print("Can't open image [" + filename + "]")
|
||||
print("Usage:")
|
||||
print("mat_mask_operations.py [image_path -- default ../../../../data/lena.jpg] [G -- grayscale]")
|
||||
return -1
|
||||
|
||||
cv2.namedWindow("Input", cv2.WINDOW_AUTOSIZE)
|
||||
@ -70,7 +70,7 @@ def main(argv):
|
||||
dst0 = sharpen(src)
|
||||
|
||||
t = (time.time() - t) / 1000
|
||||
print "Hand written function time passed in seconds: %s" % t
|
||||
print("Hand written function time passed in seconds: %s" % t)
|
||||
|
||||
cv2.imshow("Output", dst0)
|
||||
cv2.waitKey()
|
||||
@ -81,13 +81,13 @@ def main(argv):
|
||||
[-1, 5, -1],
|
||||
[0, -1, 0]], np.float32) # kernel should be floating point type
|
||||
## [kern]
|
||||
|
||||
## [filter2D]
|
||||
dst1 = cv2.filter2D(src, -1, kernel) # ddepth = -1, means destination image has depth same as input image
|
||||
dst1 = cv2.filter2D(src, -1, kernel)
|
||||
# ddepth = -1, means destination image has depth same as input image
|
||||
## [filter2D]
|
||||
|
||||
t = (time.time() - t) / 1000
|
||||
print "Built-in filter2D time passed in seconds: %s" % t
|
||||
print("Built-in filter2D time passed in seconds: %s" % t)
|
||||
|
||||
cv2.imshow("Output", dst1)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user