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: