工作需要,用到Java来图像处理,写了一手好的matlab,但工作需要就用java+opencv。然而相关资料很少,自己也就想收集一些,供大家参考,会加入一些C++与java的对比。没有归类,知道多少就贴多少,看上去有点乱,望见谅。
以下是我找到的一个OpenCV的Java教程文档!链接
opencv发的帖子,有问题请留言
类似以下这样的知识点,可以留言!!
基本操作,java版opencv跟C++版很类似。差别就是在调用函数前面加入类似Highgui.这样的库名。
Mat img=Highgui.imread(路径); //读图像跟C++一样只是多了Highgui.。
Highgui.imwrite(路径,img);//写图像
Mat img2=new Mat();
Imgproc.blur(img,img2,new Size(3,3));//光滑处理 多了Imgproc.
Imgproc.cvtColor(img,img2,Imgproc.COLOR_BGR2GRAY);//RGB==>Gray
Imgproc.equalizeHist(GrayImg,GrayImg); //直方图均衡化
List<Mat> images = new ArrayList<Mat>();
Core.split(img, images);//RGB通道分离 多了Core.
Mat mat=images.get(2);//获得第二通道分量
Core.merge(images,img);//RGB通道合并
//Java一维数组给Mat赋值 和从Mat中提取像素值保存在一维数组中
float data[] = {
1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8};
Mat mat_gray=new Mat(4,6,CvType.CV_32FC1);
Mat mat_color=new Mat(2,4,CvType.CV_32FC3);
mat_gray.put(0,0,data);//通过一维数组给灰度图像赋值
mat_color.put(0,0,data);//通过一维数组给彩色图像赋值
float data2[]=new float[mat_color.rows()*mat_color.cols()*mat_color.channels()];
mat_color.get(0,0,data2);//把mat_color中的像素值保存在一维数组中。且以为数组的类型必须跟图像数据类型CvType一致,且数组的大小得确定大于等于行数*列数*通道数。
//需要注意的是,java中Mat对数据类型很敏感。具体问题具体尝试
/****************************************************
CV_32F float
CV_16S short
CV_8S char byte
CV_8U - 8-bit unsigned integers ( 0..255 ) uchar
CV_8S - 8-bit signed integers ( -128..127 ) byte(java)
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
***************************************************/
//C++一维数组给Mat赋值和从Mat中提取像素值
float data[24]={
1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8};
Mat mat_gray=Mat(4,6,CvType.CV_32FC1,data);
Mat mat_color=Mat(2,4,CvType.CV_32FC3,data);
mat_gray.convertTo(mat_gray,CvType.CV_8UC3);
uchar *p=mat_gray.data;//数据指向p指针,就可以通过P指针获得像素值。前提是p为 uchar*型。且Mat中数据是顺序存储的。可用isContinuous()函数来判断。
for(int i=0;i<mat.cols*mat.rows*mat.channels();++i)
{
printf("%d ",*p++);
}
背景去除 简单案列,只适合背景单一的图像
private Mat doBackgroundRemoval(Mat frame)
{
// init
Mat hsvImg = new Mat();
List<Mat> hsvPlanes = new ArrayList<>();
Mat thresholdImg = new Mat();
int thresh_type = Imgproc.THRESH_BINARY_INV;
// threshold the image with the average hue value
hsvImg.create(frame.size(), CvType.CV_8U);
Imgproc.cvtColor(frame, hsvImg,
Imgproc.COLOR_BGR2HSV);
Core.split(hsvImg, hsvPlanes);
// get the average hue value of the image
Scalar average=Core.mean(hsvPlanes.get(0));
double threshValue =average.val[0];
Imgproc.threshold(hsvPlanes.get(0), thresholdImg, threshValue, 179.0, thresh_type);
Imgproc.blur(thresholdImg, thresholdImg, new Size(5, 5));
// dilate to fill gaps, erode to smooth edges
Imgproc.dilate(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);
Imgproc.erode(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 3);
Imgproc.threshold(thresholdImg, thresholdImg, threshValue, 179.0, Imgproc.THRESH_BINARY);
// create t