The return value of the submat(int rowStart, int rowEnd, int colStart, int colEnd) function is a matrix object. The content is a sub-matrix or sub-region of the original image.
First, we use imread to read the picture, and then output some information about the matrix object itself
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Core;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import origami.Origami;
public class HelloCv {
public static void main(String[] args) throws Exception {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat mat = Imgcodecs.imread("./images/test.jpg",Imgcodecs.IMREAD_GRAYSCALE);
System.out.println(mat);
}
}
Since this matrix is the original image, its isSubmat is false.
Now we use the first form of the submat function, where the input parameters are the start and end values for each row and column.
image cropping
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Core;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import origami.Origami;
public class HelloCv {
public static void main(String[] args) throws Exception {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat mat = Imgcodecs.imread("C:/HWKJ/ZRQ/OpenCv/matrixcv/images/test.jpg");
System.out.println(mat);
Mat submat = mat.submat(200, 240, 300, 350);
System.out.println(submat);
}
}
Pay attention to the size in the submat here. The size is based on the size of the original image. If it exceeds the size of the original image, an error will be reported. The error is as follows
Then we output the cropped image.
So how to confirm the range of the area you want to capture the picture? That is to say, how to determine the filling of these four parameters? Let's take the following figure as an example
Captured picture
Two other submat methods
Range(int row,int column)
row: wide start and end range, column: high start and end range
Mat submat2 = mat.submat(new Range(20,300),new Range(100,500));
Imgcodecs.imwrite("./images/output2.png",submat2);
Rect(int x, int y,int width, int height)
x: abscissa, y: ordinate, width: width, height: height
Mat submat3 = mat.submat(new Rect(0,200,100,100));
//submat3.setTo(new Scalar(255,0,0));//Draw the picture as blue
Imgcodecs.imwrite("./images/output3. png",submat3);
Open setTo as follows:
Imgcodecs.imwrite("./images/blurtest.png",mat);
Full code:
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Range;
import org.opencv.core.Core;
import org.opencv.core.Size;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import origami.Origami;
public class HelloCv {
public static void main(String[] args) throws Exception {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat mat = Imgcodecs.imread("C:/HWKJ/ZRQ/OpenCv/matrixcv/images/test.jpg");
System.out.println(mat);
Mat submat = mat.submat(200, 400, 200, 550);
//System.out.println(submat);
Imgcodecs.imwrite("./images/output.png",submat);
Mat submat2 = mat.submat(new Range(20,300),new Range(100,500));
Imgcodecs.imwrite("./images/output2.png",submat2);
Mat submat3 = mat.submat(new Rect(0,200,400,200));
submat3.setTo(new Scalar(255,0,0));
Imgcodecs.imwrite("./images/output3.png",submat3);
//Imgproc.blur(submat,submat,new Size(25.0,25.0));
Imgcodecs.imwrite("./images/blurtest.png",mat);
}
}
Image blurring
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Core;
import org.opencv.core.Size;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import origami.Origami;
public class HelloCv {
public static void main(String[] args) throws Exception {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat mat = Imgcodecs.imread("C:/HWKJ/ZRQ/OpenCv/matrixcv/images/test.jpg");
System.out.println(mat);
Mat submat = mat.submat(200, 400, 200, 550);
//System.out.println(submat);
//Imgcodecs.imwrite("./images/output.png",submat);
Imgproc.blur(submat,submat,new Size(25.0,25.0));
System.out.println("after:"+mat);
Imgcodecs.imwrite("./images/blurtest.png",mat);
}
}
submatrix generator matrix
setTo and copyTo are two very important functions in OpenCv.
setTo can set all pixels in a matrix to the specified color
copyTo can copy an existing matrix to another matrix.
The first color value represents the depth of blue, the second value represents the depth of green, and the last value represents the depth of red.
//Get red, green and blue
Scalar Red = new Scalar(0,0,255);
Scalar Green = new Scalar(0,255,0);
Scalar Blue = new Scalar(255,0,0);
We treat these colors as complementary colors to RGB. So set the other channels to a maximum value of 255 and the main channel to 0. Cyan is the complementary color of red, so the red value channel is set to 0, while the other two channels are set to 255;
Define cyan, magenta, and yellow
Scalar cyan = new Scalar(255,255,0);
Scalar magena= new Scalar(255,0,255);
Scalar yellow = new Scalar(0,255,255);
Below we use setTo to set the submatrix to a given Scalar color
private void setColors(Mat mat ,boolean comp,int row){
for (int i = 0; i <3 ; i++) {
Mat sub = mat.submat(row*100,row*100+100,i*100,i*100+100);
if(comp){
//RGB
if (i==0){
sub.setTo(Red);
}if (i==1){
sub.setTo(Green);
}if (i==2){
sub.setTo(Blue);
}
}else {
//cmy
if (i==0){
sub.setTo(cyan);
}if (i==1){
sub.setTo(magena);
}if (i==2){
sub.setTo(yellow);
}
}
}
}
Next, we create a matrix of three color channels and fill its first and second rows with
Full code:
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Range;
import org.opencv.core.Core;
import org.opencv.core.Size;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import origami.Origami;
public class HelloCv1 {
public static Scalar Red = new Scalar(0,0,255);
public static Scalar Green = new Scalar(0,255,0);
public static Scalar Blue = new Scalar(255,0,0);
public static Scalar cyan = new Scalar(255,255,0);
public static Scalar magena= new Scalar(255,0,255);
public static Scalar yellow = new Scalar(0,255,255);
public static void main(String[] args) throws Exception {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat mat = new Mat(200,300,CvType.CV_8UC3);
setColors(mat,false,1);
setColors(mat,true,0);
Imgcodecs.imwrite("./images/rgbcmy.png",mat);
}
static void setColors(Mat mat ,boolean comp,int row){
for (int i = 0; i <3 ; i++) {
Mat submat = mat.submat(row*100,row*100+100,i*100,i*100+100);
if(comp){
//RGB
if (i==0){
submat.setTo(Red);
}if (i==1){
submat.setTo(Green);
}if (i==2){
submat.setTo(Blue);
}
}else {
//cmy
if (i==0){
submat.setTo(cyan);
}if (i==1){
submat.setTo(magena);
}if (i==2){
submat.setTo(yellow);
}
}
}
}
}
generate matrix from image submatrix
First create a matrix and submatrices of size 200x200: one for the upper part of the main matrix and one for the lower part of the main matrix
int width = 200,height = 200;
Mat mat1 = new Mat(height,width,CvType.CV_8UC3);
Mat top = mat.submat(0,height/2,0,width);
Mat bottom = mat.submat(height/2,height,0,width);
Then load an image to create another small matrix and resize it to the size of the upper (or lower) submatrix. The resize function in the Imgproc class will be introduced here.
Full code:
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
import org.opencv.core.Mat;
import org.opencv.core.Rect;
import org.opencv.core.Range;
import org.opencv.core.Core;
import org.opencv.core.Size;
import org.opencv.core.MatOfInt;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import origami.Origami;
public class HelloCv1 {
public static Scalar Red = new Scalar(0,0,255);
public static Scalar Green = new Scalar(0,255,0);
public static Scalar Blue = new Scalar(255,0,0);
public static Scalar cyan = new Scalar(255,255,0);
public static Scalar magena= new Scalar(255,0,255);
public static Scalar yellow = new Scalar(0,255,255);
public static void main(String[] args) throws Exception {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
int width = 200,height = 300;
Mat mat1 = new Mat(height,width,CvType.CV_8UC3);
Mat top = mat1.submat(0,height/2,0,width);
Mat bottom = mat1.submat(height/2,height,0,width);
Mat small = Imgcodecs.imread("./images/test.jpg");
Imgproc.resize(small,small,top.size());
small.copyTo(top);
small.copyTo(bottom);
Imgcodecs.imwrite("./images/matofpictures.png",mat1);
}
NOTE: The step of setting the size is critical. The replication is successful because the size of the small matrix and the submatrix are exactly the same, so there is no problem in the replication