OpenCV网上讲的一个都不对,要么卡死电脑,要么训练模型写死,要么都只是显示显示人脸就说入门了。没有一个从安装、使用、驱动摄像头、训练模型、辩别人脸的全过程。最夸张的是连怎么安装个OpenCV的资料网上的都不全。

本篇会连续以几篇篇幅带各位入门并以最终识别人脸为全博客结束标志。读完本篇教程你将对基本人工智能算法将有了入门这一能力。为今后可以使用进一步AI应用打下扎实的基础。

在Mac系统上安装OpenCV

本系列会传授大家在两个操作系统上安装OpenCV:MAC和Win10. 这两个系统也是程序员们常用的基础,并且它的安装步骤和碰到的一些巨坑完全不同。

安装成功了,才有信心进入到HelloWorld级别代码。OpenCV安装极其复杂,当然对于没有接触过操作系统层面的程序员来说这算复杂。

其实,掌握好关键要领,一点不难,只是几分钟的事而己。

MAC上准备材料

1. OS版本

确保你的Mac为Big Sur及后续版本,笔者的Mac一直保持着最新版为Monterey12.2.1.

2. 确保Mac里的brew update为最新

这是Mac安装OpenCV前最关键的一步,很多人就卡在了这一步,最终装了10几天都没法把opencv装好,甚至把系统给装奔溃了。

因此你的brew update一定要为最新。在brew update时,经常我们会碰到卡死、或者报各种奇芭的错,99%的用户碰到的说是xcode不是最新或者说是commandline tool找不到,因此你可以使用以下步骤

sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install

稍等12-15分钟(依赖于网速和你的Mac性能),即完成了xcode的修复。

再运行

brew update

如果碰到brew已经坏了(别重装MAC哈),我经常碰到,是因为brew的很多源是在“墙外”,有时装一半掉一半导致了Mac内的brew被搞了“一股臭味”,那么没有关系,我们就可以修复我们的brew。

删除本机已经混乱或者坏了的brew

brew update-resetrm -rf /usr/local/Homebrew/Library/Taps/homebrew/homebrew-corebrew tap homebrew/core

设置国内brew镜像源

# Homebrew 源代码仓库
cd "$(brew --repo)"
git remote set-url origin https://mirrors.ustc.edu.cn/brew.git
# Homebrew 核心软件仓库
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
# Homebrew cask 软件仓库,提供 macOS 应用和大型二进制文件
cd "$(brew --repo)"/Library/Taps/homebrew/homebrew-cask
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-cask.git
# Homebrew 预编译二进制软件包
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.zshrc
source ~/.zshrc
# 更新镜像

我们使用了国内中科大源。

最后

brew update

这边再次需要各位引起重视,一定要在恒定百兆宽带基础上对xcode、brew进行update或者是运行上述修复命令。本身OpenCV还有Brew以及Mac相关的一些关键资源都是在墙外,虽然国内有一些mirror,但速度不行。

如果你的网速到达不了恒定的一秒至少5兆下载速率,你光以上几步因为失败、反复、失败就要耗费40多个小时。

对于网上说有时brew update时会碰到“git clone”或者是“error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)"。

这些的root cause就是一点:

  • 你的网络速率不行,导致git在clone超过100兆以上的东西时,自己把自己打断了;

此时如果你按照网上做以下的设置,试图先clone下来一个框子或者是把所谓的git下载时的缓存加大都是徒劳。因此,请确保你的网络至少有恒定的5兆每秒。现在100兆,200兆宽带都到家,这个已经不是条件限制了我想。

git config --global http.postBuffer 2024288000git config --listgit config --global core.compression 0git clone --depth 1 https://mirrors.ustc.edu.cn/homebrew-core.gitgit fetch --unshallow git pull --all

3. 确保必须要装ANT

除非你不想用OpenCV Java,很多人生成不了以下这两个文件就是因为忘记装ant了。

brew install ant

装完后你一定要确保你的Mac的环境变量path里可以直接访问ant命令。

如果不可以在任意地方运行ant -version命令得到ant的正确输出,你还需要手工自己在~/.bash_profile里加入ant的命令于你的path变量中去。

记得一定要是ant 1.9或者以上版本,否则装了也是白装

4. 必须记得安装python3

这个梗和上面第3点,必装ANT一样。OpenCV无论是3还是4在安装时要生成Java这两个文件,必装Python3.

brew upgrade python3

mac一般自带python2,而big sur版本中装OpenCV都用的是OpenCV4,它要求必须安装python3.

因此我们可以升级我们的本地python2至3,升级完后你原有的python2还会留着。网上会说把python3和python2互换一下。

但没必要,你可以保证python2和python3都存在。因为python2用的命令叫python,python3的命令叫python3.

这个没事的。因为我本机还有不少python2写的AI,因此我经常在两者间要用哪个时做手工切换。

5. 必须安装jdk

安装JDK17,对,你没看错。

最佳实践,在你的Mac上可以保持有jdk1.8同时还有jdk17.

现在的OpenCV无论是Windows10还是Mac下的编译安装,都会使用最新class version62版本即用的是jdk17去编译和生成的jar包。

因此同样,记得你的eclipse要用“2021-12”及以后的版本。因为在此之前的eclipse版本的compiled version只能认到jdk11最多13,因此到时你的eclipse如果不支持jdk17你在运行OpenCV的应用时,整个eclipse会因为“找不到jdk location“而最终卡死,卡到电脑CPU风扇转个不停,最后不得不”杀进程“。

然后启动eclipse用系统默认的jdk1.8,运行opencv项目用本机安装的jdk17来编译和运行以及debug

很重要,很重要,很重要,上述这一句标红的话。

这是因为,jdk17做了巨大的改变,eclipse最新版可以认出jdk17但是eclipse最新版(目前的版本)用jdk17没法在Mac上运行(因为jdk17的jre目录里的内容已经变了)。

如果你用jdk17去做成了默认的系统级path变量,那么恭喜你,你的eclipse是启动不起来的。

因此我们才有了经常本机有3个以上jdk,其中低版本一个用运启动eclipse用。其它几个版本用于不同特性的工程用。

6. 开始安装OpenCV4

到此,你可以正式安装OpenCV4了。

OpenCV4的安装过程主要涉及到以下几个核心步骤,而在Mac下是一键完成的。Mac下烦是烦在上述的第1~第2步。即xcode command line以及brew update上,这两步过了后面是一帆风顺的。如果你是在Windows10或者是Linux下安装OpenCV,你就会体会到装OpenCV4时才是最痛苦的,而在Mac上,因为有了brew,因此从这一步开始你会觉得很Hi。

OpenCV安装核心步骤(供学习者知道OpenCV在编译安装时做了什么事)

  • 下载OpenCV最新master源码;
  • 下载OpenCV 对应版本的contribute源码包(有内置图形、JAVA包、声音等);
  • 使用C编译器,生成C工程;
  • 使用C编译器,编译C工程;
  • 使用python3+ant对java文件进行编译并生成java通过jndi调用OpenCV的C的底层native lib包(在Windows10下是一个.dll文件);
  • 把C编译生成成功的release包进行系统安装;
brew edit opencv

在安装前,你要确认你的opencv内的java编译选项是turn on的。默认opencv是不会安装和编译打包java文件的。

在控制端找到-DBUILD_opencv_java=OFF 修改为-DBUILD_opencv_java=ON ,如下图所示

然后你就可以:

brew install --build-from-source opencv

接下去按照我这个机型,22分钟后,一切显示failed 0,install successfully。

你就可以看到OpenCV4正确装在了你的这个路径下了

而java用文件是生成在这边的

使用OpenCV

将/usr/local/share/java/opencv4/libopencv_java454.dylib文件拷贝到jdk的lib目录下

然后新建一个Eclipse工程。

在Eclipse工程里记得对于OpenCV的工程要做如下的jvm设置。

然后在你的eclipse工程里放置一个叫ext-lib的目录,把opencv-454.jar包放在这个目录中然后使用工程的“add external JARs...“方式添加给到工程的classpath目录下。

我们书写第一个OpenCV应用,即读入一幅图片并用于展示用。

主程序-ImageShow.java

package org.mk.opencv;import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;public class ImageShow {public static void main(String[] args) {// 载入dll或者lib包(必须先加载)System.loadLibrary(Core.NATIVE_LIBRARY_NAME);// 将文件读入为OpenCV的Mat格式。注意测试时,路径不要包括中文Mat src = Imgcodecs.imread("/Users/macuser/opt/img/ImageShow.jpg");if (src.dataAddr() == 0) {System.out.println("打开文件出错");}ImageViewer imageViewer = new ImageViewer(src, "第一幅图片");imageViewer.imshow();}
}

ImageViewer.java-用的是java swing的JFrame控件

package org.mk.opencv;import org.mk.opencv.util.OpenCVUtil;
import org.opencv.core.Mat;
import javax.swing.*;
import java.awt.*;public class ImageViewer {private JLabel imageView;private Mat image;private String windowName;/*** 如果使用junit测试时调用该方法,图像会一闪而过,可通过sleep()等方式暂时显示* * @param*/private JFrame frame = null;public ImageViewer() {frame = createJFrame(windowName, 800, 600);}public ImageViewer(Mat image) {this.image = image;}/*** @param image      要显示的mat* @param windowName 窗口标题*/public ImageViewer(Mat image, String windowName) {frame = createJFrame(windowName, 1024, 768);this.image = image;this.windowName = windowName;}public void setTitle(String windowName) {this.windowName = windowName;}public void setImage(Mat image) {this.image = image;}/*** 图片显示*/public void imshow() {setSystemLookAndFeel();frame.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 用户点击窗口关闭if (image != null) {Image loadedImage = OpenCVUtil.matToImage(image);// JFrame frame = createJFrame(windowName, image.width(), image.height());imageView.setIcon(new ImageIcon(loadedImage));frame.pack();// frame.setLocationRelativeTo(null);// frame.setVisible(true);// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 用户点击窗口关闭}}private void setSystemLookAndFeel() {try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (UnsupportedLookAndFeelException e) {e.printStackTrace();}}private JFrame createJFrame(String windowName, int width, int height) {JFrame frame = new JFrame(windowName);imageView = new JLabel();final JScrollPane imageScrollPane = new JScrollPane(imageView);imageScrollPane.setPreferredSize(new Dimension(width, height));frame.add(imageScrollPane, BorderLayout.CENTER);frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);return frame;}}

OpenCVUtil.java工具包

package org.mk.opencv.util;import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;import javax.imageio.ImageIO;import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;import org.apache.log4j.Logger;
import org.mk.opencv.face.FaceRecogFromFiles;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;public class OpenCVUtil {private static Logger logger = Logger.getLogger(OpenCVUtil.class);public static Image matToImage(Mat matrix) {int type = BufferedImage.TYPE_BYTE_GRAY;if (matrix.channels() > 1) {type = BufferedImage.TYPE_3BYTE_BGR;}int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();byte[] buffer = new byte[bufferSize];matrix.get(0, 0, buffer); // 获取所有的像素点BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type);final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);return image;}public static List<String> getFilesFromFolder(String folderPath) {List<String> fileList = new ArrayList<String>();File f = new File(folderPath);if (f.isDirectory()) {File[] files = f.listFiles();for (File singleFile : files) {fileList.add(singleFile.getPath());}}return fileList;}public static String randomFileName() {StringBuffer fn = new StringBuffer();fn.append(System.currentTimeMillis()).append((int) (System.currentTimeMillis() % (10000 - 1) + 1)).append(".jpg");return fn.toString();}public static List<FileBean> getPicFromFolder(String rootPath) {List<FileBean> fList = new ArrayList<FileBean>();int fileNum = 0, folderNum = 0;File file = new File(rootPath);if (file.exists()) {LinkedList<File> list = new LinkedList<File>();File[] files = file.listFiles();for (File file2 : files) {if (file2.isDirectory()) {// logger.info(">>>>>>文件夹:" + file2.getAbsolutePath());list.add(file2);folderNum++;} else {// logger.info(">>>>>>文件:" + file2.getAbsolutePath());FileBean f = new FileBean();String fileName = file2.getName();String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);File fParent = new File(file2.getParent());String parentFolderName = fParent.getName();f.setFileFullPath(file2.getAbsolutePath());f.setFileType(suffix);f.setFolderName(parentFolderName);fList.add(f);fileNum++;}}File temp_file;while (!list.isEmpty()) {temp_file = list.removeFirst();files = temp_file.listFiles();for (File file2 : files) {if (file2.isDirectory()) {// System.out.println("文件夹:" + file2.getAbsolutePath());list.add(file2);folderNum++;} else {// logger.info(">>>>>>文件:" + file2.getAbsolutePath());FileBean f = new FileBean();String fileName = file2.getName();String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);File fParent = new File(file2.getParent());String parentFolderName = fParent.getName();f.setFileFullPath(file2.getAbsolutePath());f.setFileType(suffix);f.setFolderName(parentFolderName);fList.add(f);fileNum++;}}}} else {logger.info(">>>>>>文件不存在!");}// logger.info(">>>>>>文件夹共有:" + folderNum + ",文件共有:" + fileNum);return fList;}public static BufferedImage matToBufferedImage(Mat matrix) {int cols = matrix.cols();int rows = matrix.rows();int elemSize = (int) matrix.elemSize();byte[] data = new byte[cols * rows * elemSize];int type;matrix.get(0, 0, data);switch (matrix.channels()) {case 1:type = BufferedImage.TYPE_BYTE_GRAY;break;case 3:type = BufferedImage.TYPE_3BYTE_BGR;// bgr to rgbbyte b;for (int i = 0; i < data.length; i = i + 3) {b = data[i];data[i] = data[i + 2];data[i + 2] = b;}break;default:return null;}BufferedImage image2 = new BufferedImage(cols, rows, type);image2.getRaster().setDataElements(0, 0, cols, rows, data);return image2;}public static Mat bufferedImageToMat(BufferedImage bi) {Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_8UC3);byte[] data = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();mat.put(0, 0, data);return mat;}
}

运行

运行ImageShow.java后得到以下效果

结速本篇教程,下一篇我们讲如何在Windows10下安装OpenCV,这个过程比起Mac OS内安装OpenCV要痛苦百倍。

但是如果按照我的博客一步步走,100%会保证你不会出错,我趟过的那些血坑你们保证再也不会趟过。

OpenCV Java入门一 在MAC系统上安装OpenCV相关推荐

  1. OpenCV Java入门二 在Windows10系统上安装OpenCV

    准备好痛苦了没有? 痛苦之后是欢乐.因为必竟大多人还是用的WINDOWS来开发的居多.因此如果OpenCV无法在Win10下安装,一样不能起到普及作用. 而Windows下的编译安装OpenCV也是最 ...

  2. 如何在mac上编写java程序_在mac系统上安装Eclipse,编写java程序

    第一步:安装java jre(java 运行环境). 如图所示: 登陆Oralce官网,点击Download选项,找到如图所示界面: 选择Java Runtime Environment(JRE),打 ...

  3. Mac系统上安装Composer

    Mac系统上安装Composer 安装脚本: php -r "copy('https://getcomposer.org/installer', 'composer-setup.php'); ...

  4. 关于如何在mac系统上安装Git并在码市上建立项目

    对Git一窍不通,为了在mac系统上安装Git,查了很多资料,走了很多弯路,一切搞定后发现其实很简单. 1.在https://brew.sh上按要求安装Homebrew. 2.在电脑终端键入brew ...

  5. Java Web项目在Mac系统上启动时提示nodename nor servname provided的解决办法

    今天在Mac系统上启动Java Web项目的时候,提示了 java . net . UnknownHostException : MAC-20150101 nodename nor servname ...

  6. 银河麒麟配置java环境_中标麒麟系统上安装Java、Eclipse指南.doc

    中标麒麟系统上安装Java环境指南 Java_NeoKylin_Install_Guide 2015-01-12 修订记录 序号 版本号 日期 修订人 摘要 1 1.0 目录Content 概述 -- ...

  7. 苹果笔记本-MAC系统 上安装使用Windows系列(win7\win8\win10)

    1.下载自己喜欢或者想用的软件,注意自己mac系统的版本(低版本或者没升过级的MAC本更需要关注),小白直接用我下方的测试时使用的版本基本没问题 下载各种虚拟机软件的地址:http://www.pc6 ...

  8. 苹果MAC系统上安装Maven并配置环境变量

    0.JDK安装及配置 a.在英文输入法的状态下,按键盘"Ctrl + 空格"组合键,调出Spotlight搜索,在这里可以快速启动终端,输入ter,然后回车,即可打开终端. b.如 ...

  9. 在mac系统上安装anaconda

    anaconda是包管理器和环境管理器,使用它可以方便地创作 在anaconda官网上下载安装包,下载链接: Anaconda | Anaconda Distribution 下载后是一个pkg文件, ...

最新文章

  1. 使用nsenter进入docker namespace
  2. 软件工程转计算机科学与技术,计算机与软件工程学院本科生转专业实施方案
  3. 【ArcGIS风暴】ArcGIS求一个矢量图层中多个图斑的“四至点”坐标案例教程
  4. java if emun_关于java:Enum与If-else
  5. 读《C++ Primer(第三版)》的一些疑问(不断更新)
  6. 浙江大学 计算机学院 秦青青,我院研究生在乒乓球大赛中喜获佳绩
  7. 数据库系统概论 -- 第一章 绪论(知识点)
  8. 有关计算机学的心得体会,关于计算机学习心得体会大全
  9. Halcon教程十二:回形针识别进阶
  10. Linux-tftp、tftpd-pha安装、使用、配置教程
  11. Android如何监听蓝牙耳机的按键事件
  12. ubuntu内核版本回退,显卡驱动降级,重装显卡驱动和cuda,cudnn
  13. 斯皮尔 皮尔森 肯德尔_在SPSS软件相关分析中,pearson(皮尔逊), kendall(肯德尔) 和spearman(斯伯曼/斯皮尔曼)三种相关分析方法有什么异同(转)...
  14. FFmpeg 视频处理
  15. 华三防火墙安全策略配置
  16. 24小时 java_Java获取24小时制的时间方法
  17. 如何进行用户行为分析
  18. Crunching Cruncher send_music_thumb_backup.png failed, see logs
  19. 在制作蓝牙小车app中遇到的坑
  20. 为什么使用双亲委派机制以及如何破坏双亲委派

热门文章

  1. HDU1411求四面体体积
  2. 移动应用广告对接:为什么SDK是最佳选择?
  3. 实际参数与形式参数的区别
  4. 从vue文件中抽取出子组件的流程及过程中踩过的坑
  5. 农庄规划软件测试,《模拟农场17》游戏评测:现代化农场让你学会如何种田
  6. 微软开源的浏览器自动化工具-Playwright
  7. Numpy 怎么把arange ()产生的列表 变成一个行向量或者列向量
  8. TMS和WMTS大概对比
  9. 最简单的商家管理系统(小白)
  10. Android launcher 桌面抽屉切换动画