/** * 人脸识别 * @throws IOException */ private CascadeClassifier faceDetector; private void initFaceDetector() throws IOException{ InputStream input = getResources().openRawResource(R.raw.haarcascade_upperbody); File cascadeDir = this.getDir("cascade", Context.MODE_PRIVATE); File file = new File(cascadeDir.getAbsoluteFile(),"haarcascade_upperbody.xml"); FileOutputStream output = new FileOutputStream(file); byte[] buff = new byte[1024]; int len = 0; while ((len = input.read(buff))!= -1){ output.write(buff,0,len); } input.close(); output.close(); faceDetector = new CascadeClassifier(file.getAbsolutePath()); } /** * 人脸识别 * @param detector */ private void faceDetect(CascadeClassifier detector){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,dst,Imgproc.COLOR_BGRA2GRAY); MatOfRect faces = new MatOfRect(); detector.detectMultiScale(dst,faces,1.1,15,0,new Size(50,50),new Size()); List<Rect> faceList = faces.toList(); if (faceList.size() >0){ for (Rect rect:faceList){ Imgproc.rectangle(src,rect.tl(),rect.br(),new Scalar(255,0,0,255),2,8,0); } } Utils.matToBitmap(src,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 对象测量 */ private void measureObjects(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY); int t = 100; Imgproc.Canny(src,dst,t,t*2,3,false); List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(dst,contours,hierarchy,Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE,new Point(0,0)); Imgproc.cvtColor(src,src,Imgproc.COLOR_GRAY2BGR); double[][] result = new double[contours.size()][2]; for(int i = 0;i <contours.size();i++){ Moments moments = Imgproc.moments(contours.get(i),false); double m00 = moments.get_m00(); double m10 = moments.get_m10(); double m01 = moments.get_m01(); double x0 = m10 /m00; double y0 = m01 /m00; double arclength = Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()),true); double area = Imgproc.contourArea(contours.get(i)); result[i][0] = arclength; result[i][1] = area; Log.d("liubin11 i = ",""+i); Log.d("liubin11 arclength = ",""+arclength); Log.d("liubin11 area = ",""+area); Imgproc.circle(src,new Point(x0,y0),2,new Scalar(255,0,0),2,8,0); } Utils.matToBitmap(src,temp); src.release(); dst.release(); hierarchy.release(); mImageView.setImageBitmap(temp); } /** * 轮廓发现 */ private void findAndDrawContours(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY); int t = 90; Imgproc.Canny(src,dst,t,t*2,3,false); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours(dst,contours,hierarchy,Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE,new Point(0,0)); Imgproc.cvtColor(src,src,Imgproc.COLOR_GRAY2BGR); for (int i =0;i<contours.size();i++){ MatOfPoint points = contours.get(i); Imgproc.drawContours(src,contours,i,new Scalar(255,0,0),2,8,hierarchy,0,new Point(0,0)); } Utils.matToBitmap(src,temp); src.release(); dst.release(); hierarchy.release(); mImageView.setImageBitmap(temp); } /** * 模板匹配 */ private void templateMat(){ Bitmap tpl = BitmapFactory.decodeResource(this.getResources(),R.drawable.fj); Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.fjy); Mat src = new Mat(); Mat tplMat = new Mat(); Utils.bitmapToMat(bitmap,src); Utils.bitmapToMat(tpl,tplMat); int width = bitmap.getWidth() - tpl.getWidth() +1; int height = bitmap.getHeight() - tpl.getHeight() +1; Mat result = new Mat(width,height,CvType.CV_32FC1);//result 必须为单通道32位 Imgproc.matchTemplate(src,tplMat,result,Imgproc.TM_CCORR_NORMED); Core.normalize(result,result,0,1.0,Core.NORM_MINMAX,-1); Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(result); Point pt = minMaxLocResult.maxLoc; Imgproc.rectangle(src,pt,new Point(pt.x+tpl.getWidth(),pt.y + tpl.getHeight()),new Scalar(255,0,0,0),2,8,0); Utils.matToBitmap(src,bitmap); src.release(); tplMat.release(); result.release(); mImageView.setImageBitmap(bitmap); } /** * 霍夫圆检测 */ private void houghCircleDet(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY); //dp 分辨率与原来的一样 ;minDist 同心圆直接间隔为5; param1 梯度阈值(基于梯度检测的);param2 相交点为100次;minRadius 最小半径;maxRadius 最大半径 Imgproc.HoughCircles(src,dst,Imgproc.CV_HOUGH_GRADIENT,1,5,100,50,30,150); Imgproc.cvtColor(src,src,Imgproc.COLOR_GRAY2BGRA); double [] circleParams = new double[3]; for (int i =0;i<dst.cols();i++){ circleParams = dst.get(0,i); Point cp = new Point(circleParams[0],circleParams[1]); Imgproc.circle(src,cp,(int)circleParams[2],new Scalar(255,0,0,255),2,8,0); } Utils.matToBitmap(src,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 霍夫直线检测(从平面坐标到极坐标) */ private void houphLinesDet(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Mat lines = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.GaussianBlur(src,src,new Size(3,3),0,0,4); int t = 20; Imgproc.Canny(src,dst,t,t*2,3,false); Mat drawImage = new Mat(src.size(),src.type()); // Imgproc.cvtColor(dst,dst,Imgproc.COLOR_GRAY2BGR); /*Imgproc.HoughLines(dst,lines,1,Math.PI/180.0,t); // Imgproc.cvtColor(dst,dst,Imgproc.COLOR_GRAY2BGR); double[] linep = new double[2]; for (int i =0;i<lines.cols();i++){ linep = lines.get(0,i); double rho = linep[0]; double theta = linep[1]; double a = Math.cos(theta); double b = Math.sin(theta); double x0 = a*rho; double y0 = b*rho; Point p1 = new Point(x0+1000*(-b),y0 + 1000*a); Point p2 = new Point(x0-1000*(-b),y0 - 1000*a); Imgproc.line(drawImage,p1,p2,new Scalar(255,0,0),2,8,0); }*/ //直接得到直线 Imgproc.HoughLinesP(dst,lines,1,Math.PI/180.0,t,15,3); double[] pts = new double[4]; for (int i =0;i<lines.cols();i++){ pts = lines.get(0,i); Point p1 = new Point(pts[0],pts[1]); Point p2 = new Point(pts[2],pts[3]); Imgproc.line(dst,p1,p2,new Scalar(255,0,0),2,8,0); } Utils.matToBitmap(dst,temp); src.release(); dst.release(); lines.release(); mImageView.setImageBitmap(temp); } /** * canny 边缘检测 * * 实际原理步骤:1、高斯模糊 * 2、梯度计算 * 3、非最大信号压制 * 4、高低阈值链接 * 5、显示 */ private void cannyEge(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY); Imgproc.GaussianBlur(src,src,new Size(3,3),0,0,4); int t = 60; Imgproc.Canny(src,dst,t,t*2,3,false);//threshold 最低阈值,threshold2 最高阈值(一般是最低阈值的2-3倍) //L2qradient = true 比false识别精度更高 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 计算图像梯度 Sobel 算子 / Scharr 算子 */ private void sobleGradient(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); int type = 2; if(type ==1) {//x方向 //ddepth = -1 不变 ; dx = 1 x方向求导 ; // Imgproc.Sobel(src, dst, -1, 1, 0);//x方向梯度(x方向1阶求导) // Imgproc.Sobel(src,dst,CvType.CV_16S,1,0);//x方向梯度(x方向求导) 深度为CvType.CV_16S效果比-1要清晰 Imgproc.Scharr(src,dst,CvType.CV_16S,1,0);//Scharr算子,深度设为CvType.CV_16S,若为-1 可能不起作用,因为溢出了 Core.convertScaleAbs(dst,dst);//求绝对值,去除负数 Utils.matToBitmap(dst,temp); }else if (type ==2) {//y方向 // Imgproc.Sobel(src,dst,-1,0,1);//y方向梯度(y方向求导) // Imgproc.Sobel(src,dst,CvType.CV_16S,0,1);//y方向梯度(y方向求导) 深度为CvType.CV_16S效果比-1要清晰 Imgproc.Scharr(src,dst,CvType.CV_16S,0,1);//Scharr算子,深度设为CvType.CV_16S,若为-1 可能不起作用,因为溢出了 Core.convertScaleAbs(dst,dst);//求绝对值,去除负数 Utils.matToBitmap(dst,temp); }else {//x,y 方向梯度结合使用 Mat xdst = new Mat(); Mat ydst = new Mat(); // Imgproc.Sobel(src, xdst, CvType.CV_16S, 1, 0); // Imgproc.Sobel(src, ydst, CvType.CV_16S, 0, 1); Imgproc.Scharr(src, xdst, CvType.CV_16S, 1, 0); Imgproc.Scharr(src, ydst, CvType.CV_16S, 0, 1); Core.convertScaleAbs(xdst, xdst); Core.convertScaleAbs(ydst, ydst); Mat xydst = new Mat(); Core.addWeighted(xdst, 0.5, ydst, 0.5, 30, xydst);//x,y 方向的权重都是0.5 Utils.matToBitmap(xydst, temp); xdst.release(); ydst.release(); xydst.release(); } src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 直方图均衡化 */ private void histogramEq(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(selectBitmap,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY);//必须转为灰度图,单通道 Imgproc.equalizeHist(src,dst);//直方图均衡化 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(selectBitmap); } /**局部阈值: * 自适应阈值--均值C * 自适应阈值--高斯C */ private void adaptiveThresholdBinary(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY);//转为8位灰度单通道图 //自适应阈值 // Imgproc.adaptiveThreshold(src,dst,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,391,0.0); //高斯C Imgproc.adaptiveThreshold(src,dst,255,Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY,591,0.0); Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /**全局阈值: * 阈值二值化 * 阈值反二值化 * 阈值截断 * 阈值取0 * 阈值取0反 */ private void thresholdImg(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY);//转为8位灰度单通道图 //thresh 为指定阈值,若此值指定则以此值为阈值,若设置为0,最后一个参数加上Imgproc.THRESH_OTSU 则自动计算阈值 // Imgproc.threshold(src,dst,166,255,Imgproc.THRESH_BINARY);//阈值二值化 // Imgproc.threshold(src,dst,166,255,Imgproc.THRESH_BINARY_INV);//阈值反二值化 // Imgproc.threshold(src,dst,0,255,Imgproc.THRESH_BINARY |Imgproc.THRESH_OTSU);//自动阈值二值化 // Imgproc.threshold(src,dst,0,255,Imgproc.THRESH_BINARY_INV |Imgproc.THRESH_OTSU);//自动阈值反二值化 // Imgproc.threshold(src,dst,0,255,Imgproc.THRESH_TRUNC |Imgproc.THRESH_OTSU);//阈值截断 // Imgproc.threshold(src,dst,0,255,Imgproc.THRESH_TOZERO |Imgproc.THRESH_OTSU);//阈值取0 Imgproc.threshold(src,dst,0,255,Imgproc.THRESH_TOZERO_INV |Imgproc.THRESH_OTSU);//阈值取0反 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 直线识别(横线) */ private void morphLineDetection(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY);//转成灰度图(单通道) Imgproc.threshold(src,src,0,255,Imgproc.THRESH_BINARY_INV | Imgproc.THRESH_OTSU);//二值化处理 //strElement 结构元素形态的选取,此处Imgproc.MORPH_RECT 为特殊矩形,高为1 Mat strElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(20,1),new Point(-1,-1)); Imgproc.morphologyEx(src,dst,Imgproc.MORPH_OPEN,strElement);//开操作 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 开(先腐蚀再膨胀),闭(先膨胀再腐蚀) 操作 */ private void openOrClose(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2GRAY);//转成灰度图(单通道) Imgproc.threshold(src,src,0,255,Imgproc.THRESH_BINARY_INV | Imgproc.THRESH_OTSU);//二值化处理 //strElement 结构元素形态的选取 Mat strElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(3,3),new Point(-1,-1)); // Imgproc.morphologyEx(src,dst,Imgproc.MORPH_OPEN,strElement);//开操作 Imgproc.morphologyEx(src,dst,Imgproc.MORPH_CLOSE,strElement);//闭操作 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 图片腐蚀(既最小值滤波)和膨胀(既最大值滤波) */ private void erodeOrDilate(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); //结构形态的选取 Mat strElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(3,3),new Point(-1,-1)); // Imgproc.erode(src,dst,strElement,new Point(-1,-1),5);//腐蚀, 最后一个参数,表示执行几次腐蚀 Imgproc.dilate(src,dst,strElement,new Point(-1,-1),5);//膨胀,最后一个值表示执行1次膨胀 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 自定义滤波器 */ private void customFilter(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Mat kernel = getCustomOperator(); Imgproc.filter2D(src,dst,-1,kernel,new Point(-1,-1),0.0,4); Utils.matToBitmap(dst,temp); kernel.release(); src.release(); dst.release(); mImageView.setImageBitmap(temp); } private Mat getCustomOperator(){ Mat kernel = new Mat(3,3,CvType.CV_32FC1);//自定义滤波算子,必须是基数 如此处的(3,3) kernel.put(0,0,1.0/9.0,1.0/9.0,1.0/9.0,1.0/9.0,1.0/9.0,1.0/9.0,1.0/9.0,1.0/9.0,1.0/9.0);//模糊 // kernel.put(0,0,-1,-1,-1,-1,8,-1,-1,-1,-1);//拉普拉斯边缘 // kernel.put(0,0,-1,-1,-1,-1,9,-1,-1,-1,-1);//拉普拉斯边缘锐化 return kernel; } /** * 双边模糊 */ private void biBlur(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,src,Imgproc.COLOR_BGRA2BGR);//4通道转3通道,双边模糊只支持3通道,或单通道,而Bitmap是4通道的,要做转换 Imgproc.bilateralFilter(src,dst,15,150,15,4);//双边模糊 Mat kernel = new Mat(3,3,CvType.CV_16S); kernel.put(0,0,0,-1,0,-1,5,-1,0,-1,0); Imgproc.filter2D(dst,dst,-1,kernel,new Point(-1,-1),0,4);//锐化处理 Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 高斯模糊 速度没有均值模糊快 */ private void gaussianBlur(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); //Size 中若不为0则以size中的计算,若为0则已sigmaX,Y来计算模糊范围 Imgproc.GaussianBlur(src,dst,new Size(3,3),0,0,4); Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 均值模糊 */ private void meanBlur(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Mat dst = new Mat(); Utils.bitmapToMat(temp,src); //Size 表示内核的大小(也叫算子) 都必须为正数和奇数,模糊范围如(9,9) 表示x方向9个像素,y方向9个像素,如(1,9) 表示只在y方向做模糊 //Point (-1,-1)表示默认为内核中心点 //最后一个参数 用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT Imgproc.blur(src,dst,new Size(1,35),new Point(-1,-1),4); Utils.matToBitmap(dst,temp); src.release(); dst.release(); mImageView.setImageBitmap(temp); } /** * 截取图片指定区域 */ private void getROIArea(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Rect roi = new Rect(200,150,200,300); Bitmap roimap = Bitmap.createBitmap(roi.width,roi.height,Bitmap.Config.ARGB_8888); Mat src = new Mat(); Utils.bitmapToMat(temp,src); Mat roiMat = src.submat(roi);//截取指定位置图片 Mat roiDstMat = new Mat(); Imgproc.cvtColor(roiMat,roiDstMat,Imgproc.COLOR_BGR2GRAY);//转灰度图 Utils.matToBitmap(roiDstMat,roimap); roiDstMat.release(); roiMat.release(); src.release(); mImageView.setImageBitmap(roimap); } /** * 创建空白的Mat */ private void creatMat(){ Bitmap bitmap = Bitmap.createBitmap(400,600,Bitmap.Config.ARGB_8888); // Mat dst = new Mat(bitmap.getHeight(),bitmap.getWidth(),CvType.CV_8UC1,new Scalar(100));//CU_8UC1 表示一个通道,所以后面的Scalar也只有一个通道 Mat dst = new Mat(bitmap.getHeight(),bitmap.getWidth(),CvType.CV_8UC4,new Scalar(255,0,0,255));//通道顺序agbr Utils.matToBitmap(dst,bitmap); dst.release(); mImageView.setImageBitmap(bitmap); } /** * 转灰度图 */ private void convert3Gray(){ Mat src = new Mat(); Mat dst = new Mat(); Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Utils.bitmapToMat(temp,src); Imgproc.cvtColor(src,dst,Imgproc.COLOR_BGR2GRAY); Utils.matToBitmap(dst,temp); src.release();//必须释放内存 dst.release(); mImageView.setImageBitmap(temp); } /** * 利用Mat像素反转 */ private void invert(){ Mat src = new Mat(); Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Utils.bitmapToMat(temp,src); //pixel options int width = src.cols(); int height = src.rows(); int cnum = src.channels();//通道数,如 ARGB_8888 占4个通道 byte[] bgra = new byte[cnum]; long startTime = System.currentTimeMillis(); for (int row = 0; row <height;row++){ for (int col = 0;col < width;col++){ src.get(row,col,bgra);//将row行,col列的像素,保存到bgra中 for (int i = 0;i< cnum;i++){ bgra[i] = (byte)(255 -bgra[i]&0xff);//0xff 使得byte 不发生有符号拓展,使用一个掩码来限制. 主要对负数的限制 } src.put(row,col,bgra); } } long end = System.currentTimeMillis() - startTime; Log.d(TAG,"inver total time "+ end); Utils.matToBitmap(src,temp); src.release(); mImageView.setImageBitmap(temp); } /** * 利用Mat像素反转 */ private void invert2(){ Mat src = new Mat(); Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Utils.bitmapToMat(temp,src); long startTime = System.currentTimeMillis(); Core.bitwise_not(src,src); long end = System.currentTimeMillis() - startTime; Log.d(TAG,"invert2 total time "+ end); Utils.matToBitmap(src,temp); src.release(); mImageView.setImageBitmap(temp); } /** * 像素减法 */ private void subStract(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Utils.bitmapToMat(temp,src); Mat whiteImg = new Mat(src.size(),src.type(), Scalar.all(255));//创建一个白色的Mat 大小和src必须一样 long startTime = System.currentTimeMillis(); Core.subtract(whiteImg,src,src); long end = System.currentTimeMillis() - startTime; Log.d(TAG,"subStract end = "+end); Utils.matToBitmap(src,temp); src.release(); whiteImg.release(); mImageView.setImageBitmap(temp); } /** * 像素加法 */ private void add(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Utils.bitmapToMat(temp,src); Mat whiteImg = new Mat(src.size(),src.type(), Scalar.all(255));//创建一个白色的Mat 大小和src必须一样 long startTime = System.currentTimeMillis(); // Core.add(whiteImg,src,src); Core.addWeighted(whiteImg,0.5,src,0.5,0,src); long end = System.currentTimeMillis() - startTime; Log.d(TAG,"subStract end = "+end); Utils.matToBitmap(src,temp); src.release(); whiteImg.release(); mImageView.setImageBitmap(temp); } /** * 调整对比度和亮度 */ private void adjustContrast(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); Mat src = new Mat(); Utils.bitmapToMat(temp,src); src.convertTo(src, CvType.CV_32F);//转成32位的浮点数,为后面能使用浮点数计算所要做的步骤 Mat whiteImg = new Mat(src.size(),src.type(), Scalar.all(1.25));//创建一个白色的Mat 大小和src必须一样 Mat bwImg = new Mat(src.size(),src.type(),Scalar.all(30)); long startTime = System.currentTimeMillis(); Core.multiply(whiteImg,src,src);//对各像素先乘以1.25 Core.add(bwImg,src,src);//再对各个像素加个30 long end = System.currentTimeMillis() - startTime; Log.d(TAG,"subStract end = "+end); src.convertTo(src,CvType.CV_8U);//将src转为CV_8U,才能转为Bitmap Utils.matToBitmap(src,temp); src.release(); whiteImg.release(); bwImg.release(); mImageView.setImageBitmap(temp); } /** * 利用Bitmap 的缓存中做像素反转 */ private void bitmapInvert(){ Bitmap temp = selectBitmap.copy(selectBitmap.getConfig(),true); int width = temp.getWidth(); int height = temp.getHeight(); int [] pixels = new int[width*height]; temp.getPixels(pixels,0,width,0,0,width,height); int index = 0; int a = 0,r = 0,g = 0,b = 0; long startTime = System.currentTimeMillis(); for (int row = 0;row < height;row ++){ index = row*width; for (int col = 0;col < width ;col ++){ int pixel = pixels[index]; a = (pixel>>24)&0xff; r = (pixel>>16)&0xff; g = (pixel>>8)&0xff; b = (pixel&0xff); r = 255 -r;//反转 g = 255 -g; b = 255 -b; pixel = ((a&0xff)<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff); pixels[index] = pixel; index++; } } long end = System.currentTimeMillis() - startTime; Log.d(TAG,"bitmap getPixels end = "+ end); temp.setPixels(pixels,0,width,0,0,width,height); mImageView.setImageBitmap(temp); }
Open CV 3.4基础API使用
最新推荐文章于 2025-05-19 08:53:21 发布