Java+OpenCV⽬标检测
Java+OpenCV⽬标检测
简介:⼤学⽣⼀枚,加⼊了学校项⽬组学习,参与到项⽬中,最近项⽬需要,通过各⽅⾯的学习,做了⼀个⼩⼩的物体识别的
环境:jdk1.8 opencv 3.4.0
⾸先,我们要有⾜量的图像,我相信这个各位是有办法收集到⾃⼰想要检测的⽬标的图像的。实际训练过程中,我发现500左右已经可以⼤体上识别到⾃⼰想要的⽬标,但是如果想要更⾼的精度,建议在1000+的正⾯例⼦,反⾯例⼦的话只要⾥⾯没有⽬标图像,可以是任何图像,但是建议根据实际需要,在所处的场景中截取不含正⾯例⼦的图像作为反⾯例⼦。据了解,正:反最佳⽐例是1:3左右哦。
下⾯开始上代码了,我把需要的东西都整合了,只需要图像⽂件地址就可以把所需的⽂件⽣成进⾏训练的操作。
import Core;
import Mat;
import Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
public class Project{
//下⾯都是⽂件src,根据⾃⼰的实际情况填写
public static String posFilePath ="";//正⾯例⼦源⽂件夹
public static String posOutPath ="";//正⾯例⼦输出⽂件夹
public static String posTxtPath ="";//正⾯例⼦信息txt⽂件
public static String negFilePath ="";//反⾯例⼦源⽂件夹
public static String NegOutPath ="";//反⾯例⼦输出⽂件夹
public static String negTxtPath ="";//反⾯例⼦信息txt⽂件
//修改⽂件⼤⼩为20*20 可⾃定义设置,根据opencv官⽅推荐20*20效果最佳,
//个⼈建议最⼤不要超过40*40,太⼤的话跑不太动
public static int width =20;
public static int height =20;
//导⼊opencv库
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void renameFiles(String filePath){
File file =new File(filePath);
File[] files = file.listFiles();
int i =0;
for(File f : files){
i++;
}
}
/
/获取img和txt的过程
/*
* 1、对图⽚缩放⾄20*20
* 2、对图⽚进⾏灰度处理
* 3、获取Txt
* */
public static void getPosImgAndTxt()throws IOException {
File infile =new File(posFilePath);//获取正⾯例⼦的⽂件夹
File infile =new File(posFilePath);//获取正⾯例⼦的⽂件夹
File outfile =new File(posOutPath);//缩放和灰度处理后的例⼦存放⽂件夹
File txtFile =new File(posTxtPath);//txt信息⽂件的⽂件位置
if(txtFile.isDirectory()){
System.out.println("txt⽂件别忘了在⽂件夹地址后加上⽂件名");
return;
}
if(!ists()){
System.out.println("⽂件不存在,⾃动创建完毕");
}
if(!ists()){
outfile.mkdir();
System.out.println("输出路径不存在,⾃动创建完毕");
}
if(!infile.isDirectory()){
System.out.println("请确保参数posFilePath为⽂件夹路径");
}else if(infile.isDirectory()){
File[] files = infile.listFiles();
FileOutputStream fileOutputStream =new FileOutputStream(txtFile);
PrintWriter printWriter =new PrintWriter(fileOutputStream,true);
for(File file :files){
Mat mat = Imgcodecs.Path());
//缩放
/
/灰度处理
Imgproc.cvtColor(mat,mat,Imgproc.COLOR_BGR2GRAY,0);
//获取图⽚
Imgcodecs.imwrite(outfile+"\\"+Name()+".jpg",mat);
//添加⽂件信息到txt⽂件中
printWriter.Path()+"\\"+Name()+" 1 0 0 20 20");
}
printWriter.close();
fileOutputStream.close();
}
}
/
/获取反⾯img和txt的过程
/*
*1、对图⽚进⾏灰度处理
*2、获取txt
* */
public static void getNegImgAndTxt()throws IOException {
File infile =new File(negFilePath);//获取反⾯例⼦的⽂件夹
File outfile =new File(NegOutPath);//灰度处理后的例⼦存放⽂件夹
File txtFile =new File(negTxtPath);//txt信息⽂件的⽂件位置
if(txtFile.isDirectory()){
System.out.println("txt⽂件别忘了在⽂件夹地址后加上⽂件名");
return;
}
if(!ists()){
System.out.println("⽂件不存在,⾃动创建完毕");
}
if(!ists()){
outfile.mkdir();
System.out.println("输出路径不存在,⾃动创建完毕");
}
if(!infile.isDirectory()){
System.out.println("请确保参数posFilePath为⽂件夹路径");
}else if(infile.isDirectory()){
}else if(infile.isDirectory()){
File[] files = infile.listFiles();
FileOutputStream fileOutputStream =new FileOutputStream(txtFile);
PrintWriter printWriter =new PrintWriter(fileOutputStream,true);
for(File file :files){
Mat mat = Imgcodecs.Path());
//灰度处理
Imgproc.cvtColor(mat,mat,Imgproc.COLOR_BGR2GRAY,0);
//获取图⽚
Imgcodecs.imwrite(outfile+"\\"+Name()+".jpg",mat);
//添加⽂件信息到txt⽂件中
printWriter.Path()+"\\"+Name());
}
printWriter.close();
fileOutputStream.close();
}
}
public static void main(String[] args)throws IOException {
/*
* 如果有需要,可以调⽤重命名函数,因为图像⽂件名中是
* 不可以有汉字的我的例⼦图像好多都是通过qq截图截的,其中含有“截图”这两个字,
* 所以被迫写⼀个重命名的函数,我把图像的名字都改成了数字
* 重命名函数已经写好,可以直接调⽤
* renameFiles(参数);
* 参数路径中不要有不是作为⽬标检测素材的其他⽂件,因为如果有⾮图像⽂件
* 需要的参数是⽂件夹路径,会将整个⽂件夹中的⽂件重命名为数字.jpg 的格式
*
rectangle函数opencv* */
getPosImgAndTxt();
getNegImgAndTxt();
}
}
经过上⾯的操作,我们的⽂件夹应该是这个样⼦的(见下图)
然后我们在这个⽂件夹⾥⾯创建⼀个名为xml的⽂件夹,⽤来保存训练所得的l以及其他每⼀层的⽂件
-vec pos.vec - -num 500 -w 20 -h 20
其中,-num 是指你的正⾯例⼦的个数, -w 是指我们的正⾯例⼦的宽度 ,-h 是指我们的正⾯例⼦的⾼度。
这段代码执⾏后,会⽣成⽂件pos.vec
然后在cmd中本⽂件夹⽬录下输⼊:
-data xml -vec pos.vec - -numPos 500 -numNeg 1500 -numStages 15 -w 20 -h 20 -minHitRate 0.999 -maxFalseAlarmRate 0.2 -weightTrimRate 0.95 -featureType LBP
其中-numStage是指训练层数,可以根据实际情况⾃⼰定,我⾃⼰跑的时候,由于跑到stage15~16附近就已经很慢了,所以我选择了15层,实际训练过程中发现样本数量越少跑起来越慢,在这段代码回车后会进⾏⼀段时间的模型训练在xml那个⽂件夹中⽣成⼀堆xml⽂件,⽤得到的是l
这时候xml⽂件夹中是这样的:
然后就是对我们的模型进⾏应⽤啦代码如下:
import *;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import java.io.File;
public class New {
public static void main(String[] args){
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
CascadeClassifier carDetector =new CascadeClassifier("E:\\new2\\xml\\l");//调取训练出来的模型
String filepath="E:\\project\\outputcam1";//输⼊路径,
String outPath="E:\\project\\success";//输出路径
File file=new File(filepath);
File outfile=new File(outPath);
if(!ists()){
outfile.mkdir();
}if(!file.isDirectory()){
System.out.println("请输⼊正确的⽂件夹路径");
}else if(file.isDirectory()){
String[] fileList=file.list();
for(String imgName:fileList){
Mat img = Imgcodecs.imread(filepath+"/"+imgName);
MatOfRect detections =new MatOfRect();
carDetector.detectMultiScale(img,detections);
int i =0;
for(Rect rect :Array()){
//将识别到的⽬表物体框起来
//将框出来⽬标的图像输出
Imgcodecs.imwrite(outPath+"/"+imgName, img);
i ++;
}
}
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论