Commit 45afd29b authored by tribta's avatar tribta

Tutorial Mask Operations on Matrices

parent 954e2f9b
...@@ -28,24 +28,39 @@ the zero-zero index) on the pixel you want to calculate and sum up the pixel val ...@@ -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 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. notation is a lot easier to look over.
Code
----
@add_toggle_cpp @add_toggle_cpp
Now let us see how we can make this happen by using the basic pixel access method or by using the You can download this source code from [here
@ref cv::filter2D function. ](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 @end_toggle
@add_toggle_java @add_toggle_java
Now let us see how we can make this happen by using the basic pixel access method or by using the You can download this source code from [here
**Imgproc.filter2D()** function. ](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 @end_toggle
@add_toggle_python @add_toggle_python
Now let us see how we can make this happen by using the basic pixel access method or by using the You can download this source code from [here
**cv2.filter2D()** function. ](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 @end_toggle
The Basic Method 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: Here's a function that will do this:
@add_toggle_cpp @add_toggle_cpp
@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp basic_method @snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp basic_method
...@@ -132,37 +147,38 @@ The filter2D function ...@@ -132,37 +147,38 @@ The filter2D function
Applying such filters are so common in image processing that in OpenCV there exist a function that 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 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: to define an object that holds the mask:
@add_toggle_cpp @add_toggle_cpp
@snippet samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp kern @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 @end_toggle
@add_toggle_java @add_toggle_java
@snippet samples/java/tutorial_code/core/mat_mask_operations/MatMaskOperations.java kern @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 @end_toggle
@add_toggle_python @add_toggle_python
@snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py kern @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: 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 @snippet samples/python/tutorial_code/core/mat_mask_operations/mat_mask_operations.py filter2D
@end_toggle @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 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 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. milliseconds the first took around 31 milliseconds. Quite some difference.
...@@ -172,22 +188,7 @@ For example: ...@@ -172,22 +188,7 @@ For example:
![](images/resultMatMaskFilter2D.png) ![](images/resultMatMaskFilter2D.png)
@add_toggle_cpp @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 Check out an instance of running the program on our [YouTube
channel](http://www.youtube.com/watch?v=7PF1tAU9se4) . channel](http://www.youtube.com/watch?v=7PF1tAU9se4) .
@youtube{7PF1tAU9se4} @youtube{7PF1tAU9se4}
@end_toggle @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; ...@@ -2,14 +2,10 @@ import org.opencv.core.Core;
import org.opencv.core.CvType; import org.opencv.core.CvType;
import org.opencv.core.Mat; import org.opencv.core.Mat;
import org.opencv.core.Scalar; import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc; import org.opencv.imgproc.Imgproc;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
class MatMaskOperationsRun { class MatMaskOperationsRun {
public void run(String[] args) { public void run(String[] args) {
...@@ -31,8 +27,10 @@ class MatMaskOperationsRun { ...@@ -31,8 +27,10 @@ class MatMaskOperationsRun {
System.exit(-1); System.exit(-1);
} }
Image img = toBufferedImage(src); HighGui.namedWindow("Input", HighGui.WINDOW_AUTOSIZE);
displayImage("Input", img, 0, 200); HighGui.namedWindow("Output", HighGui.WINDOW_AUTOSIZE);
HighGui.imshow( "Input", src );
double t = System.currentTimeMillis(); double t = System.currentTimeMillis();
Mat dst0 = sharpen(src, new Mat()); Mat dst0 = sharpen(src, new Mat());
...@@ -40,8 +38,9 @@ class MatMaskOperationsRun { ...@@ -40,8 +38,9 @@ class MatMaskOperationsRun {
t = ((double) System.currentTimeMillis() - t) / 1000; t = ((double) System.currentTimeMillis() - t) / 1000;
System.out.println("Hand written function time passed in seconds: " + t); System.out.println("Hand written function time passed in seconds: " + t);
Image img2 = toBufferedImage(dst0); HighGui.imshow( "Output", dst0 );
displayImage("Output", img2, 400, 400); HighGui.moveWindow("Output", 400, 400);
HighGui.waitKey();
//![kern] //![kern]
Mat kern = new Mat(3, 3, CvType.CV_8S); Mat kern = new Mat(3, 3, CvType.CV_8S);
...@@ -58,8 +57,10 @@ class MatMaskOperationsRun { ...@@ -58,8 +57,10 @@ class MatMaskOperationsRun {
t = ((double) System.currentTimeMillis() - t) / 1000; t = ((double) System.currentTimeMillis() - t) / 1000;
System.out.println("Built-in filter2D time passed in seconds: " + t); System.out.println("Built-in filter2D time passed in seconds: " + t);
Image img3 = toBufferedImage(dst1); HighGui.imshow( "Output", dst1 );
displayImage("Output", img3, 800, 400);
HighGui.waitKey();
System.exit(0);
} }
//! [basic_method] //! [basic_method]
...@@ -108,38 +109,12 @@ class MatMaskOperationsRun { ...@@ -108,38 +109,12 @@ class MatMaskOperationsRun {
return Result; return Result;
} }
//! [basic_method] //! [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 class MatMaskOperations {
public static void main(String[] args) { public static void main(String[] args) {
// Load the native library. // Load the native library.
System.loadLibrary(Core.NATIVE_LIBRARY_NAME); System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new MatMaskOperationsRun().run(args);
new MatMaskOperationsRun().run(args); // run code
} }
} }
from __future__ import print_function
import sys import sys
import time import time
import numpy as np import numpy as np
import cv2 import cv2
## [basic_method] ## [basic_method]
def is_grayscale(my_image): def is_grayscale(my_image):
return len(my_image.shape) < 3 return len(my_image.shape) < 3
...@@ -26,7 +27,6 @@ def sharpen(my_image): ...@@ -26,7 +27,6 @@ def sharpen(my_image):
height, width, n_channels = my_image.shape height, width, n_channels = my_image.shape
result = np.zeros(my_image.shape, my_image.dtype) result = np.zeros(my_image.shape, my_image.dtype)
## [basic_method_loop] ## [basic_method_loop]
for j in range(1, height - 1): for j in range(1, height - 1):
for i in range(1, width - 1): for i in range(1, width - 1):
...@@ -36,17 +36,16 @@ def sharpen(my_image): ...@@ -36,17 +36,16 @@ def sharpen(my_image):
result[j, i] = saturated(sum_value) result[j, i] = saturated(sum_value)
else: else:
for k in range(0, n_channels): 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] \ sum_value = 5 * my_image[j, i, k] - my_image[j + 1, i, k] \
- my_image[j, i + 1, k] - my_image[j, i - 1, 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) result[j, i, k] = saturated(sum_value)
## [basic_method_loop] ## [basic_method_loop]
return result return result
## [basic_method] ## [basic_method]
def main(argv): def main(argv):
filename = "../data/lena.jpg" filename = "../../../../data/lena.jpg"
img_codec = cv2.IMREAD_COLOR img_codec = cv2.IMREAD_COLOR
if argv: if argv:
...@@ -57,8 +56,9 @@ def main(argv): ...@@ -57,8 +56,9 @@ def main(argv):
src = cv2.imread(filename, img_codec) src = cv2.imread(filename, img_codec)
if src is None: if src is None:
print "Can't open image [" + filename + "]" print("Can't open image [" + filename + "]")
print "Usage:\nmat_mask_operations.py [image_path -- default ../data/lena.jpg] [G -- grayscale]" print("Usage:")
print("mat_mask_operations.py [image_path -- default ../../../../data/lena.jpg] [G -- grayscale]")
return -1 return -1
cv2.namedWindow("Input", cv2.WINDOW_AUTOSIZE) cv2.namedWindow("Input", cv2.WINDOW_AUTOSIZE)
...@@ -70,7 +70,7 @@ def main(argv): ...@@ -70,7 +70,7 @@ def main(argv):
dst0 = sharpen(src) dst0 = sharpen(src)
t = (time.time() - t) / 1000 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.imshow("Output", dst0)
cv2.waitKey() cv2.waitKey()
...@@ -81,13 +81,13 @@ def main(argv): ...@@ -81,13 +81,13 @@ def main(argv):
[-1, 5, -1], [-1, 5, -1],
[0, -1, 0]], np.float32) # kernel should be floating point type [0, -1, 0]], np.float32) # kernel should be floating point type
## [kern] ## [kern]
## [filter2D] ## [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] ## [filter2D]
t = (time.time() - t) / 1000 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) cv2.imshow("Output", dst1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment