java 版 opencv 实现图片素描处理

package hsytest;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class HsyOpencvUtils {

    static {
        // 解决awt报错问题
        System.setProperty("java.awt.headless", "false");
        System.out.println("java.library.path = " + System.getProperty("java.library.path"));
        // 加载动态库
        // URL url = ClassLoader.getSystemResource("opencv_java341.dll");
        // URL url = HsyOpencvTest.class.getResource("opencv_java320.dll");
        // String path = url.toString();
        // System.out.println( "path = " + path );
        System.load( "E:\\git\\study\\opencvHandleImg-master\\out\\production\\Opencv\\opencv_java320.dll" );
    }

    public static void imageBinarization( String imagePath,String outputPath ){
        Mat mat_src = Imgcodecs.imread( imagePath );
        Imgproc.cvtColor(mat_src, mat_src, Imgproc.COLOR_RGB2GRAY);
        Imgproc.adaptiveThreshold(mat_src, mat_src, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 25, 10);
        Imgcodecs.imwrite(outputPath, mat_src);
    }

    public static void drawContours( String imagePath,String outputPath ){
        Mat src = Imgcodecs.imread( imagePath );
        //将源图像转换为二进制
        Mat gray = new Mat(src.rows(), src.cols(), src.type());
        Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
        Mat binary = new Mat(src.rows(), src.cols(), src.type(), new Scalar(0));
        Imgproc.threshold(gray, binary, 100, 255, Imgproc.THRESH_BINARY_INV);
        //寻找轮廓
        List<MatOfPoint> contours = new ArrayList<>();
        Mat hierarchey = new Mat();
        Imgproc.findContours(binary, contours, hierarchey, Imgproc.RETR_TREE,
                Imgproc.CHAIN_APPROX_SIMPLE);
        // Iterator<MatOfPoint> it = contours.iterator();
        // while(it.hasNext()) {
        //     System.out.println(it.next());
        // }
        Mat draw = Mat.zeros(binary.size(), CvType.CV_8UC3);
        for (int i = 0; i < contours.size(); i++) {
            // System.out.println(contours);
            Scalar color = new Scalar(0, 0, 255);
            //绘图轮廓
            Imgproc.drawContours(draw, contours, i, color, 2, Imgproc.LINE_8, hierarchey, 2, new Point() ) ;
        }
        Imgcodecs.imwrite(outputPath, draw);
    }

    public static void xxx(){
        Mat mat_src = Imgcodecs.imread("E:\\sucai\\video\\avatar\\plane.jpg");
        for( int code = 0;code<=139;code++ ){
            Mat mat_dest = new Mat();
            try {
                Imgproc.cvtColor(mat_src, mat_dest, code);
            }catch ( Exception e ){
                System.err.println( "不支持的 code " + code );
                continue;
            }
            try {
                Imgcodecs.imwrite( "E:\\sucai\\video\\avatar\\plane_code" + code + ".jpg",mat_dest );
            }catch ( Exception e){
                System.err.println( "Imgcodecs.imwrite 出现问题" );
            }
        }
        // Imgproc.cvtColor(mat_src, mat_dest, Imgproc.COLOR_BGR2RGB);

        //
        // Core.inRange(hsv, new Scalar(100, 100, 100), new Scalar(255, 255, 255), mask);

        //去掉人物区域,留下背景
      /*  Mat person = new Mat();
        Core.bitwise_not(mask, mask);
        Core.bitwise_and(src, src, person, mask);*/

        //生成蓝色背景
       /* Mat result = Mat.zeros(src.size(), src.type());
        result.setTo(new Scalar(255, 0, 0));*/

        //更换背景
      /*  Mat dst = new Mat();
        Core.bitwise_not(mask, mask);
        Core.bitwise_or(person, result, dst, mask);
        Core.add(dst, person, dst);*/
    }

    public static void sketchOperation( String imagePath,String outputPath ){
        // 原始 mat
        Mat mat_src = Imgcodecs.imread( imagePath );

        // 原始 mat 进行灰度处理之后的 mat
        Mat mat_gray = HsyOpencvUtils.getGrayMat( mat_src );
        Imgcodecs.imwrite( "E:\\sucai\\video\\avatar\\mat_gray.jpg",mat_gray );

        // 灰色取反
        Mat mat_gray_negate = getNegateMat( mat_gray );
        Imgcodecs.imwrite( "E:\\sucai\\video\\avatar\\mat_gray_negate.jpg",mat_gray_negate );

        // 对灰色取反后的mat再进行高斯模糊
        Mat mat_gray_negate_gaussianBlur = HsyOpencvUtils.gaussianBlur( mat_gray_negate );
        Imgcodecs.imwrite( "E:\\sucai\\video\\avatar\\mat_gray_negate_gaussianBlur.jpg",mat_gray_negate_gaussianBlur );

        // 将 mat_gray_negate_gaussianBlur 进行取反
        Mat mat_gray_negate_gaussianBlur_negate = HsyOpencvUtils.getNegateMat( mat_gray_negate_gaussianBlur );
        Imgcodecs.imwrite( "E:\\sucai\\video\\avatar\\mat_gray_negate_gaussianBlur_negate.jpg",mat_gray_negate_gaussianBlur_negate );

        // 将 mat_gray 和 mat_gray_negate_gaussianBlur_negate 进行 divide 操作
        Mat mat_dst = new Mat();
        Core.divide( mat_gray,mat_gray_negate_gaussianBlur_negate,mat_dst,255d );
        Imgcodecs.imwrite( "E:\\sucai\\video\\avatar\\mat_dst.jpg",mat_dst );
    }

    /**
     * 对原始mat进行高斯模糊处理
     * @param mat_src
     * @return
     */
    private static Mat gaussianBlur(Mat mat_src) {
        Mat mat_dst = new Mat();
        Imgproc.GaussianBlur( mat_src,mat_dst,new Size(15, 15),50,50 );
        return mat_dst;
    }

    /**
     * 对原始 mat 进行灰度处理
     * @param mat_src
     * @return
     */
    public static Mat getGrayMat( Mat mat_src ){
        Mat mat_gray = new Mat();
        Imgproc.cvtColor(mat_src, mat_gray, Imgproc.COLOR_RGB2GRAY);
        return mat_gray;
    }

    /**
     * 对原始的 灰度图 mat 进行取反操作( 即新灰度mat 的每个像素的值 = 255 - 原始灰度图的每个像素的值  )
     * @param mat_src
     * @return
     */
    public static Mat getNegateMat( Mat mat_src ){
        Mat mat_negate = new Mat();
        mat_src.copyTo( mat_negate );
        int rowCount = mat_src.rows();
        int colCount = mat_src.cols();
        for( int row = 0;row<rowCount;row++ ){
            for( int col=0;col<colCount;col++ ){
                double value = mat_src.get(row, col)[ 0 ];
                Double value_new = 255d-value;
                int[] ints = new int[ 1 ];
                ints[ 0 ] = value_new.intValue();
                mat_negate.put( row,col,value_new );
            }
        }
        return mat_negate;
    }


     /**
     * xxx 浮雕
     * @param imagePath
     * @param outputPath
     */
    public static void xxxReliefOperation( String imagePath,String outputPath){
        Mat mat_src = Imgcodecs.imread(imagePath);
        Mat mat_gray = HsyOpencvUtils.getGrayMat(mat_src);
        Mat mat_dst = new Mat();
        mat_gray.copyTo( mat_dst );

        int rowCount = mat_gray.rows();
        int colCount = mat_gray.cols();
        rowCount--;
        colCount--;
        for( int row=0;row<rowCount;row++ ){
            for( int col=0;col<colCount;col++ ){
                double v1 = mat_gray.get(row, col)[0];
                double v2 = mat_gray.get(row+1, col+1)[0];
                Double v = v1-v2+70d;
                if( v > 255d ){
                    v = 255d;
                }else if( v<0 ){
                    v = 0d;
                }
                mat_dst.put( row,col,v );
            }
        }
        Imgcodecs.imwrite( outputPath,mat_dst );
    }


     /**
     * 油画特效
     * @param imagePath
     * @param outputPath
     */
    public static void oilPaintingOperation( String imagePath,String outputPath ){
        long t = System.currentTimeMillis();
        Mat mat_src = Imgcodecs.imread(imagePath);
        Mat mat_gray = HsyOpencvUtils.getGrayMat(mat_src);
        Mat mat_dst = new Mat();
        mat_gray.copyTo( mat_dst );
        int height = mat_gray.rows();
        int width = mat_gray.cols();
        int[] array = new int[ 8 ];
        for( int row=4;row<( height - 4 );row++ ){
            for( int col=4;col< ( width - 4 );col++ ){
                // int[] array = new int[ 8 ];
                array[ 0 ] = 0;
                array[ 1 ] = 0;
                array[ 2 ] = 0;
                array[ 3 ] = 0;
                array[ 4 ] = 0;
                array[ 5 ] = 0;
                array[ 6 ] = 0;
                array[ 7 ] = 0;
                for( int m =-4;m<=4;m++ ){
                    int row1 = row + m;
                    for( int n=-4;n<=4;n++ ){
                        // 0 ~ 7
                        Double index = mat_gray.get(row1, col + n)[0] / 32;
                        array[ index.intValue() ]++;
                    }
                }
                // 求 array 的最大值以及对应角标
                int value_max = array[0];
                int index_max = 0;
                for( int index=1;index<=7;index++ ){
                    int value_curr = array[index];
                    if( value_max < value_curr ){
                        value_max = value_curr;
                        index_max = index;
                    }
                }
                double[] bgr = null;

                int v1 = index_max * 32;
                int v2 = ( index_max + 1 ) * 32;
                for( int m=-4;m<=4;m++ ){
                    int row1 = row + m;
                    for( int n=-4;n<=4;n++ ){
                        int col1 = col + n;
                        double v = mat_gray.get( row1, col1 )[ 0 ];
                        if( v >= v1 && v <= v2 ){
                            bgr = mat_src.get( row1, col1 );
                        }
                    }
                }
                mat_dst.put( row,col,bgr );
            }
        }
        Imgcodecs.imwrite( outputPath,mat_dst );
        System.out.println( "耗时:" + ( System.currentTimeMillis() - t ) + "毫秒" );
    }
}
package hsytest;

import java.io.File;

public class HsyOpencvTest {

    public static void main(String[] args) {
        String imagePath = "E:\\sucai\\video\\avatar\\zhoujielun.jpeg";
        HsyOpencvUtils.sketchOperation( imagePath,"E:\\sucai\\video\\avatar\\zhoujielun_sketch.jpg" );
    }

}

图片效果:

周杰伦.jpeg:

 mat_gray.jpg:

mat_gray_negate.jpg:

mat_gray_negate_gaussianBlur.jpg:

mat_gray_negate_gaussianBlur_negate.jpg:

mat_dst.jpg:

猜你喜欢

转载自blog.csdn.net/heshiyuan1406146854/article/details/130122849