这是opencv4android的第三篇,从这里开始就简单的写,要不我没有时间去学别的了!大家加油。
检测边缘的一种算法,是一个二阶导数就是Sobel的导数,可以这么理解,是边界轮廓更加清晰明显。
方法: Laplacian(grayMat,dstMat,-1,3,1,0,Core.BORDER_DEFAULT);
参数说明:原图像,目标图像,深度,内核大小,后三个为默认值。
代码:
Mat grayMat=new Mat();
Utils.bitmapToMat(mBitmap,rgbMat);
Imgproc.GaussianBlur(rgbMat,grayMat,new Size(3,3),0,0,Core.BORDER_DEFAULT);
Imgproc.cvtColor(grayMat,grayMat,Imgproc.COLOR_BGR2GRAY);
Imgproc.Laplacian(grayMat,dstMat,-1,3,1,0,Core.BORDER_DEFAULT);
Utils.matToBitmap(dstMat,dstBitmap);
dstImage.setImageBitmap(dstBitmap);
效果:
从效果图上来看,确实要比Sobel的边缘检测效果要好很多,能够很明显的看出帽子上羽毛的轮廓。
Canny 边缘检测算法 是 John F. Canny 于 1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的 最优算法, 最优边缘检测的三个主要评价标准是:
方法:Imgproc.Canny(grayMat,dstMat,n,3*n,3,true);
参数:灰度图像,目标图像,最低阈值,最高阈值,内核大小,不知道。
代码:
Mat grayMat=new Mat();
Utils.bitmapToMat(mBitmap,rgbMat);
Imgproc.cvtColor(rgbMat,grayMat,Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(grayMat,grayMat,new Size(3,3),0,0,Core.BORDER_DEFAULT);
Imgproc.Canny(grayMat,dstMat,n,3*n,3,true);
Utils.matToBitmap(dstMat,dstBitmap);
dstImage.setImageBitmap(dstBitmap);
解释一下,先灰度之后高斯平滑,之后在边缘检测。
效果图:
在解释一下,进度条最大值代表最低阈值,也就是第三个参数,第四个参数是第三个的2-3倍最好,我使用3倍,内核是3,opencv教程中使用的归一块平滑,我用的是高斯,可能效果上有所差异,不过轮廓的清晰度还是很好的。
霍夫线变换是一种用来寻找直线的方法.
是用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像.
在写这个的时候已经距离我写之前的两个有一个礼拜的时间了。这个霍夫线变化实在是有点费劲,主要是在容器的创建和使用上,完全搞不懂,如果有会的希望能给我留言,交流一下, QQ755457743.标准的霍夫线变换没写,因为那个容器没法弄,搞了好几天都没搞好,都准备弃了,统计概率霍夫线变换写出来了,不过感觉不对啊,跟opencv教程上的差好多,不过也算是弄出来了,就发一下看看。
方法: HoughLinesP(Mat image, Mat lines, double rho, double theta, int threshold, double minLineLength, double maxLineGap)
参数:
其中最费劲的就是这个lines容器,Mat对象。完全不知道怎么写。各种尝试。最后在stackoverflow看到一个人的回答,参照他的写法才勉强弄出图像的。
代码:
Mat srcMat=new Mat();
Mat dstMat=new Mat();
Mat thresholdImage=new Mat();
Utils.bitmapToMat(mBitmap,srcMat);
Imgproc.cvtColor(srcMat,thresholdImage,Imgproc.COLOR_BGR2GRAY,4);
Imgproc.cvtColor(srcMat,dstMat,Imgproc.COLOR_BGR2RGB,4);
Imgproc.Canny(thresholdImage,thresholdImage,50,200,3,true);
Mat lines=new Mat();
int threshold=50,minLineSize=50,lineGap=10;
Imgproc.HoughLinesP(thresholdImage,lines,1,1,n,n,lineGap);
// Imgproc.HoughLines(thresholdImage,lines,1,1,n,0,0);
for(int i=0;i
效果图:
可以看出来,只是有线的效果,而且只有在阈值特别低的情况下才能明显的感觉到有窗户,感觉是我写的不对。在上面的代码中,主要的坑就是在第二个参数坐标的容器,卡了好久,完全没有思路,现在的这种方式也是借鉴来的,自己加了一些改动,可能是自己对于矩阵这个容器的理解不是很深刻,上面你的代码我也不是很理解,矩阵搞得每一个元素都存储了两个点的坐标,也就是一条直线的起点和终点,我不知道对不对。
跟霍夫线变换类似用于检测圆的,这个写的没问题,不过需要根据阈值拉调整。
方法: HoughCircles(Mat image, Mat circles, int method, double dp, double minDist, double param1, double param2, int minRadius, int maxRadius)
参数:
代码:
Mat src=new Mat();
Mat dst=new Mat();
Mat gray=new Mat();
Utils.bitmapToMat(mBitmap,src);
Imgproc.cvtColor(src,gray,Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(gray,gray,new Size(9,9),2,2);
Mat circles=new Mat();
Imgproc.HoughCircles(gray,circles,Imgproc.CV_HOUGH_GRADIENT,1,gray.rows()/8,4*n,100,0,0);
for(int i=0;i
这个代码是没有问题的,效果也是可以的,如果没有达到预期可能是因为param_1的参数问题。
效果图:
可以看到不同的值对应这不同的圆。
把一个图像中一个位置的像素放置到另一个图片指定位置的过程.这个效果没有实现,只实现了像素的挪动没有达到opencv中的效果。
方法:
remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation, int borderMode, Scalar borderValue)
参数:
代码:
if(rgbMat==null|dstMat==null){
rgbMat=new Mat();
dstMat=new Mat();
}
Utils.bitmapToMat(mBitmap,rgbMat);
Mat src_x=new Mat(rgbMat.size(),CvType.CV_32FC1);
Mat src_y=new Mat(rgbMat.size(),CvType.CV_32FC1);
for(int j=1;j
效果图:
参照opencv教程中代码,经过自己的理解和改写之后在opencv4android中实现效果就这样,能够看出来确实像素点的位置对调了,但是像素值却发生了改变,不清楚为什么会发生这种情况,个人猜测是因为src_y和src_x的原因,我也尝试了不用的位置偏差,和混合方式,结果都不行,像素值在转换过来之后都发生了改变。至此无果。
opencv4android到现在已经写了4篇了,从环境搭建道基本使用,说实话我都不知道这个东西是干嘛的,就只是朋友要就学了一点,之后自己感兴趣就多学了一些,不过到这里也就结束了,这一篇是暂时的完结,也不知道以后会不会写, 因为这个东西对于现在的我来说实在是费劲,从图像的知识到C再到opencv,心力交瘁,有时候一个很简单的东西都会卡很久,兴趣也变成无趣了,为自己之前的狂妄自大说个对不起,就到这里了,写不下去。