• [技术干货] 使用OpenCV,构建文档扫描仪
    本文将使用 OpenCV,创建一个简单的文档扫描仪,就像常用的摄像头扫描仪应用程序一样。这个想法很简单,因为我们认为文档是四边形,我们获取边缘的位置并使用它来抓取文档本身,而忽略无用的图像背景。简单的管道:加载图像>>检测边缘和抓取位置>>使用图像上的位置导入包首先,我们导入处理图像可能需要的包。threshold_local 函数对你来说可能看起来很新,但这段代码其实没有什么特别之处。该函数来自 scikit 图像包。# import packagesfrom skimage.filters import threshold_localimport numpy as npimport cv2import imutils加载图像。在这里,我们加载图像并保留一份副本。在这里,原始的副本对于获得清晰且未经篡改的图像扫描非常重要。为了处理图像,我调整到一个合理的比例,接下来我对图像进行灰度化以减少颜色并使其模糊(即有助于从图像背景中去除高频噪声),这些都是为了找到文件的边缘。#load in the imageimage = cv2.imread("images/questions.jpg")orig  = image.copy()#Resize the image.height = image.shape[0]width = image.shape[1]ratio = 0.2width = int(ratio * width)height = int(ratio * height)image = cv2.resize(image,(width, height))#find edges in the image.gray_scaled = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#blurr the imagegray_scaled = cv2.GaussianBlur(gray_scaled,(5,5),0)#Edge detectionedged = cv2.Canny(gray_scaled,50, 200)cv2.imshow("Image", image)cv2.waitKey(0)cv2.imshow("Edges detected", edged)cv2.waitKey(0)找到轮廓。使用 cv2.findcontours() 找到轮廓。接下来,我们使用 imutils 库抓取轮廓,最后,我们根据最大轮廓区域,对抓取的轮廓进行排序。在这种情况下,我保留了最大的 5 个# find contours in the edged image. keep only the largest contours.contours = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# grab contourscontours = imutils.grab_contours(contours)# select contours based on size.contours = sorted(contours, key=cv2.contourArea, reverse = True)[:5]对轮廓进行进一步处理。首先,我们遍历轮廓并找到周长,这是将周长近似为点所必需的。完成此操作后,我们最终搜索恰好具有 4 个点的轮廓,这很可能是近似矩形形状的纸张。完成后,我们获取这些点的坐标,然后将它们初始化为纸张轮廓。# loop over the contours.for contour in contours:   perimeter = cv2.arcLength(contour, True)   # approximate your contour   approximation = cv2.approxPolyDP(contour, 0.02*perimeter, True)      # if our contour has 4 points, then surely, it should be the paper.   if len(approximation) == 4:       paper_outline = approximation       break有了坐标,下一步就是画轮廓,很简单。# Draw the found contour.cv2.drawContours(image,[paper_outline],-1,(225,0,0),2)cv2.imshow("Found outline", image)cv2.waitKey(0)你心中的问题是,我们完成了吗?好吧,你可能会说是的,因为你在图像周围设置了很好的轮廓。答案是否定的,为了获得最佳扫描形式的图像,我们需要 90 度的图像视图,尤其是在倾斜的情况下。为此,我们将创建一个函数来处理此任务。管道:排列点>>标记点>>从真实图像中挑选点arrange_points 函数。这样做的方法非常简单,归功于 Adrian Rosebrock(博士)。这个函数背后的直觉是我们获取文档四个边缘的坐标,并将其安排到我们认为它应该在的位置,我花了一些时间给出描述的图形表示。点坐标的和1)从上图中我们可以看出,点坐标(X,Y)的和最大的是在右上角。2)最小的点总和是左下点。点坐标的差3)点坐标的差的最大值是左上角4)点坐标的差的最小值是左下角。代码。该函数接受参数points,接下来,我初始化一个 NumPy 数组来表示矩形,该数组是一个 4 x 2 矩阵,因为我们有 4 个点和 2 个坐标(X,Y)。最后,如上所述,我在矩形的点中注册(点的和以及点的差)。最后,我正确地返回了 Rectangle 的坐标。def arrange_points(points):   # initialize a list of co-ordinates that will be ordered   # first entry is top-left point, second entry is top-right   # third entry is bottom-right, forth/last point is the bottom left point.   rectangle = np.zeros((4,2), dtype = "float32")      # bottom left point should be the smallest sum   # the top-right point will have the largest sum of point.   sum_points= points.sum(axis =1)   rectangle[0] = points[np.argmin(sum_points)]   rectangle[2] = points[np.argmax(sum_points)]         #bottom right will have the smallest difference   #top left will have the largest difference.   diff_points = np.diff(points, axis=1)   rectangle[1] = points[np.argmin(diff_points)]   rectangle[3] = points[np.argmax(diff_points)]         # return order of co-ordinates.   return rectangle设置四个点。这个功能很简单,这里的想法当然是拉直纸张,只提取需要的区域。在这里,输入是 1) 图像本身和点或坐标。首先,我们使用我们创建的第一个函数“arrange_points”来排列函数的点。接下来,我相应地分配了点,因为我之前已经安排了点并且也很好地命名了它们。计算。对于计算,只需两点之间的距离即可找到每边的长度。有了这个,我们能够在对的位置上防止错误地调整图像。顾名思义,目的地是图像的新视图。其中 [0,0] 表示左上角。接下来,[Max-width - 1,0] 表示右上角,我们还有 [maxwidth -1, maxheight-1] 表示底部右上角,最后是左下角 [0, max-height -1]。转换矩阵动作完成,工作结束,我们需要完成的是使用 cv2.getPerspectiveTransform() 的变换矩阵,它接受点的矩形和目的地。现在我们有了矩阵,我们使用 cv2.warpPerspective() 应用它,它获取你提供给函数的图像、变换矩阵,最后是建议扫描的(宽度和长度)。全部完成,返回转换后的图像# set four points.def set_four_points(image, points):   # obtain order of points and unpack.   rectangle = arrange_points(points)   (top_left,top_right,bottom_right,bottom_left) = rectangle   # let's compute width of the rectangle.   # using formular for distance between two points   left_height = np.sqrt(((top_left[0]-bottom_left[0])**2) + ((top_left[1]-bottom_left[1])**2))   right_height = np.sqrt(((top_right[0]-bottom_right[0])**2) + ((top_right[1]-bottom_right[1])**2))   top_width = np.sqrt(((top_right[0]-top_left[0])**2) + ((top_right[1]-top_left[1])**2))   bottom_width = np.sqrt(((bottom_right[0]-bottom_left[0])**2) + ((bottom_right[1]-bottom_left[1])**2))      maxheight = max(int(left_height), int(right_height))   maxwidth  = max(int(top_width), int(bottom_width))      destination = np.array([       [0,0],       [maxwidth -1,0],       [maxwidth -1, maxheight-1],       [0, maxheight - 1]], dtype = "float32")                matrix = cv2.getPerspectiveTransform(rectangle, destination)      warped = cv2.warpPerspective(image, matrix, (maxwidth,maxheight))      return warped应用函数我们已经创建了函数,因此我们将其应用于最初保存的原始图像。第二个输入是论文的大纲。我通过删除我在开始时所做的比例缩放,将纸张轮廓重新调整回原来的大小。要获得图像的黑白感觉,需要使用 Threshold local,但当然,如果你想要对图像进行彩色扫描,则根本不需要它。最后,我调整大小并显示。warped = set_four_points(orig, paper_outline.reshape(4,2)*(1/ratio))#warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)#threshold = threshold_local(warped, 11, offset=10, method="gaussian")#warped = (warped > threshold).astype("uint8") * 255#show the original and scanned imagesprint("Image Reset in progress")cv2.imshow("Original", cv2.resize(orig,(width, height)))cv2.imshow("Scanned",cv2.resize(warped,(width, height)))cv2.waitKey(0)干得好!!,你刚刚创建了自己的扫描仪应用程序。       原文标题 : 构建文档扫描仪
  • [技术干货] Python中OpenCV的基础知识
    从安装到基本图像处理OpenCV 是一个流行的开源库,可用于不同的编程语言,例如 Python、C++ 和 JavaScript。它提供了一套丰富的工具来处理和分析图像和视频,让你可以从调整单张图片的大小到构建复杂的对象识别应用程序。Python 编程语言除了被广泛用作大多数图像处理和计算机视觉应用程序的标准外,还允许以非常直接的方式将 OpenCV 安装在你的计算机中。在本教程中,我将向你展示使用 OpenCV 安装、设置和对图像执行一些基本操作所需的步骤,重点介绍有关该库背后概念的重要基础知识。值得一提的是,这些步骤是在基于 Linux 的操作系统中使用Python3执行的。因此,如果你使用不同的配置,则可能需要进行细微的更改。设置虚拟环境使用 Python 时,通常建议在虚拟环境中运行你的应用程序。这样做,你可以只安装运行应用程序所需的包,使其独立于系统的其余部分。如果你的计算机上仍然没有安装虚拟环境工具,我建议你安装以下工具。python3 -m pip install virtualenv安装后,你可以使用此工具创建新的虚拟环境。为此,导航到你想要的目录并运行以下命令。请注意,我为我的环境选择了名称 my_venv,但你可以选择任何你想要的名称。python3 -m venv my_venv最后,你只需要激活你的虚拟环境,以便你在此终端中运行的任何内容都将在其中完成。source my_venv/bin/activate安装 OpenCV首先更新你的包管理器并为 Python3 安装 OpenCV。sudo apt updatesudo apt install python3-opencv然后,使用 pip 在你的虚拟环境中安装 OpenCV。pip install opencv-python打开图像使用你最喜欢的 IDE,创建一个扩展名为 .py 的新文件,然后从导入 OpenCV 类开始import cv2我们在这里做的第一件事是使用 imread() 方法加载图像并使用 imshow() 方法打开它。请将下面的路径替换为你的图片所在的路径。image = cv2.imread("images/messi.jpg")cv2.imshow("Original image", image)原始图像关于 OpenCV 如何解释图像的第一个有趣的点是,imread()返回一个n 维数组对象。对于 RGB 图像,例如本例中使用的图像,此数组具有以下形状:[宽×高×通道数]你可以通过打印图像形状来确认这一点。print("Original image shape:", image.shape)更改图像色彩空间颜色空间是用于描述图像的光谱上的一系列颜色。尽管有多种颜色空间可用,但最常见的是 RGB 和灰度。OpenCV 包含一种特殊的颜色空间转换方法。为了将图像从 RGB 转换为灰度,你需要应用 cvtColor()方法。image_grayscale = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)cv2.imshow(“Grayscale image”, image_grayscale)灰度图像重要的是要注意,现在你的图像不再包含三个维度。那是因为对应于通道的第三维在灰度色彩空间中没有使用。print("Grayscale image shape:", image_grayscale.shape)编辑图像通道返回到包含三个颜色通道的原始图像,你现在可以操纵每个通道的强度值,以抑制或突出显示特定通道。与通常假设的相反,RGB 通道的访问顺序与首字母缩写词中的顺序不同。在 OpenCV 中,通道实际上以 BGR 格式提供:0 = B(蓝色)1 = G(绿色)2 = R(红色)在下面的示例中,我检索前两个通道中的所有像素并将它们设为零,这样绿色和蓝色通道将不会对生成的图像产生任何影响,因此图像将呈现完全红色调。image_red = image.copy()image_red[:, :, :2] = 0 cv2.imshow("Red image", image_red)具有空蓝色和绿色通道的图像打印红色图像形状时,请注意仍然存在第三维,否则生成的图像将被描述为灰度print("Red image shape:", image_red.shape)旋转图像除了颜色之外,还可以对图像形状进行操作,例如大小和方向。你可以从获取图像尺寸开始,就像 NumPy 对象一样。width, height, _ = image.shape然后可以通过取其宽度和高度的一半来计算图像的中心点。center = (width//2, height//2)为了旋转图像,你首先必须创建一个旋转矩阵,分别将中心点、所需的旋转度数和图像比例作为参数传递。使用不同于 1 的比例会改变图像大小。rotation_matrix = cv2.getRotationMatrix2D(center, 45, 1.0) 旋转矩阵对象本身不足以做我们想要的。它作为参数传递给 warpAffine() 方法,这是实际执行旋转的方法。image_rotated = cv2.warpAffine(image, rotation_matrix, (width, height))cv2.imshow(“Rotated image”, image_rotated)旋转图像调整图像大小你可以使用之前获得的高度和宽度值来定义图像的新尺寸。在下面的示例中,我将它们设置为将图像缩小到其原始大小的三分之一。new_size = (width//3, height//3)负责调整图像大小的方法是resize(),它分别需要原始图像对象、所需的新大小和插值方法作为参数。image_resized = cv2.resize(image, new_size, interpolation=cv2.INTER_LINEAR)cv2.imshow(“Resized image”, image_resized)调整大小的图像然后,你可以检查调整大小的图像的尺寸。print(“Resized image shape:”, image_resized.shape)将绘图插入图像在某些应用程序中,可能需要向图像添加标记。OpenCV 类提供了多种在其上绘制线条和形状的方法。如下添加一行。这里的参数是原始图像、初始位置、最终位置、线条颜色 RGB 代码和线条宽度。请注意,实际上使用的是原始图像的副本,因为绘图方法会影响原始图像。image_line = cv2.line(image.copy(), (0, 0), (height//2, width//2), (0, 255, 255), 10)cv2.imshow(“Image with line”, image_line)带线条的图像同样,在图像中绘制矩形也有特定的方法。在这种情况下,第二个和第三个参数是矩形相对顶点的位置(左上角和右下角)。image_rectangle = cv2.rectangle(image.copy(), (500, 150), (900, 550), (0, 255, 255), 5)cv2.imshow(“Image with rectangle”, image_rectangle)带有矩形的图像你还可以通过将圆的中心位置和半径分别指定为第二个和第三个参数来绘制一个圆。image_circle = cv2.circle(image.copy(), (300, 300), 200, (0, 255, 255), 5)cv2.imshow(“Image with circle”, image_circle)带圆的图像       原文标题 : Python中OpenCV的基础知识
  • [技术干货] 鲲鹏服务器OpenCV的安装
    步骤一:下载Opencvgit clone -b 4.3.0 https://gitee.com/mirrors/opencv.gitcd opencvmkdir buildcd build步骤二:安装opencvcmake -D BUILD_SHARED_LIBS=ON  \-D BUILD_TESTS=OFF \-D CMAKE_BUILD_TYPE=RELEASE \-D CMAKE_INSTALL_PREFIX=/home/HwHiAiUser/ascend_ddk/arm \-D WITH_LIBV4L=ON make -j8 make install步骤三:配置opencv的环境变量 export PATH=/home/HwHiAiUser/ascend_ddk/arm/bin:$PATH export LD_LIBRARY_PATH=/home/HwHiAiUser/ascend_ddk/arm/lib:$ LD_LIBRARY_PATH
  • [技术干货] 玩转Atlas 200DK(五)OpenCV的安装
    五、OpenCV的安装8、使用MindStudio运行YoLoV3样例工程我们记得上次说到OpenCV的安装比较麻烦。是因为OpenCV需要实现交叉编译,即需要在开发环境x86上编译aarch64的包,然后编译好的可执行程序需要在运行环境aarch64上运行。另外,由于mksd制卡方式和dd镜像制卡方式有点区别。dd镜像方式中很多包昇腾团队已经给我们准备好了。所以在下列的一些(shao)操作里面,张小白会特意提到,如果是mksd制卡方式,需要做哪些操作(言下之意就是,如果是dd方式,那些在200dk ubuntu 18.04 aarch环境上的一些操作就可以省略了。(1)打开YoLoV3样例工程打开一个新的YoLoV3工程,可参考:https://gitee.com/ascend/samples/tree/master/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture会提示:此时点击OK:在弹出的菜单中再点击OK即可打开这个YoLoV3工程。此时,还是需要再配置一个deployment的:add一个server:像前面描述一样的增加 connection和mapping即可:当然,编译YoLoV3的工程代码同样也会报找不到OpenCV的问题:我们来看看怎么解决这个问题。CANN训练营的龙哥  @海中之龙  是个爱学习的好童鞋。他给张小白提供了一个解决方案:https://gitee.com/ascend/samples/blob/master/cplusplus/environment/separate_environmental_guidance_CN.md#%E5%AE%89%E8%A3%85opencv跟着好学生做应该能成功,不妨试一下吧!(2)安装OpenCV方式1:dd镜像制卡的运行环境如果是dd镜像制卡的运行环境,按以下操作进行:cd /usr/lib/aarch64-linux-gnusudo scp -r HwHiAiUser@192.168.1.2:/lib/aarch64-linux-gnu/* ./sudo scp -r HwHiAiUser@192.168.1.2:/usr/lib/aarch64-linux-gnu/* ./。。。sudo scp -r HwHiAiUser@192.168.1.2:/usr/lib/*.so.* ./# 拷贝opencv相关头文件。sudo scp -r HwHiAiUser@192.168.1.2:/usr/include/opencv /usr/include/sudo scp -r HwHiAiUser@192.168.1.2:/usr/include/opencv2 /usr/include/。。。方式2:mksd制卡的运行环境这种环境下,运行环境基本上没有开发包。所以需要在200DK上安装OpenCV:.。。x86环境copy回对应的so:cd /usr/lib/aarch64-linux-gnusudo scp -r HwHiAiUser@192.168.1.2:/lib/aarch64-linux-gnu/* ./sudo scp -r HwHiAiUser@192.168.1.2:/usr/lib/aarch64-linux-gnu/* ./sudo scp -r HwHiAiUser@192.168.1.2:/usr/lib/*.so.* ./sudo scp -r HwHiAiUser@192.168.1.2:/usr/include/opencv* /usr/include(其实仔细看看,除了需要在运行环境200DK上安装OpenCV之外,后续的拷贝动作跟mksd都是一样的。)(3)执行编译build:这里比较奇怪,前面OpenCV没报错了,但是后面又去找了 runtime的目录,这个CMakeLists.txt文件确实写得有问题,至少是不适合交叉编译使用。张小白检查了下上图中的link_librarys, 原来这个runtime目录跟实际的目录不对应:张小白做了以下的修改:(在原来的runtime目录前增加了 一层arm64-linux目录)再重新编译,成功了!(4)YoLoV3的模型转换打开 https://gitee.com/ascend/samples/tree/master/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_pictureA、下载caffe模型需要先到200DK上执行以下命令:cd $HOME/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/modelwget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/yolov3.caffemodelwget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/yolov3.prototxtwget https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/YOLOV3_coco_detection_picture/aipp_nv12.cfgB、在运行环境(200DK)的命令行中完成模型转换:atc --model=yolov3.prototxt --weight=yolov3.caffemodel --framework=0 --output=yolov3 --soc_version=Ascend310 --insert_op_conf=aipp_nv12.cfgC、将转换好的离线模型拷贝到开发环境在X86上执行:cd ~/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/modelscp HwHiAiUser@192.168.1.2:/home/HwHiAiUser/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/model/yolov3.om .D、准备待推理的图片cd ../datawget https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/YOLOV3_coco_detection_picture/dog1_1024_683.jpg --no-check-certificate(4)代码运行在MindStudio的菜单中选择Run:等了一会儿,运行结果如下:查看本地out/output目录下生成的结果图片:确实 dog 99%已在结果图中标识出来了。9、再次使用MindStudio打开venc样例工程回过头来打开dvpp的venc的项目,这个时候应该也能编译和运行了:这里面的细节就不细说了,跟前面处理的方式几乎一样。(未完待续)
  • [其他] OpenCV做两幅图像的融合
    将把文本图像与漂亮的背景图像混合在一起。让我们先来看看这两个图像: ![ce4f0d53e1cb194491d1bd284b6bb057.jpg](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651063001517117968.jpg) ![a74822baf5011f6a11c9ba58b581d087.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651063006616493518.png) bg = cv2.imread('images/background.jpg', cv2.IMREAD_COLOR) fg = cv2.imread('images/foreground.png', cv2.IMREAD_COLOR) 我们先调整图像大小,以确保它们的尺寸相同。要使融合能够正常进行,需要使用相同的大小图像。否则,它将返回错误消息。 (.shape)背景图像为853到1280像素。前景图像为1440至2560像素。我们将使用OpenCV的调整大小功能调整它们的大小。 dim = (1200, 800) resized_bg = cv2.resize(bg, dim, interpolation = cv2.INTER_AREA) resized_fg = cv2.resize(fg, dim, interpolation = cv2.INTER_AREA) 有了OpenCV,我们可以用一行代码来完成这项工作。将为我们完成混合的功能称为addWeighted。它有5个参数,可以列出为:图像源1,src1权重,图像源2,src2权重,伽玛。每个图像的权重值必须小于1。这是混合方程式: blend = (image scr1)*(src1 weight) + (image scr2)*(src2 weight) + gamma 这是函数的数学原理。让我们看看实际情况: `blend = cv2.addWeighted(resized_bg, 0.5, resized_fg, 0.8, 0.0)` 我们给前景加了一些权重。这样,背景将更暗,文本将更亮。 现在,让我们使用imwrite方法导出最终作品。这是将图像另存为文件夹中的新图像文件的行。 `cv2.imwrite('blended.png', blend)` ![e943055c4cae902df419236c8a6ba475.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651063157864826198.png)
  • [技术干货] cv2.error: OpenCV(4.5.4-dev) D:\a\opencv-python\opencv-python\op
     - 1.查看自己的路径当中是否出现中文,如果有的话修改路径 - 2.如果路径不存在问题,则要注意转义的问题     (如果路径出现"\"的话需要在路径最前边加r,意思是防止转义.)     (如果是"/"则不存在其他问题)
  • [问题求助] 【Atlas200DK】【OpenCV兼容问题】atlas200DK是否兼容OpenCV库?
    【功能模块】模块兼容问题【操作步骤&问题现象】想请问atlas200DK的芯片是否支持OpenCV库?【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [问题求助] 如何在200DK的开发和运行分设环境下安装opencv的交叉编译环境
    参见 https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=184545&ordertype=2&page=2在使用MindStudio 3.0.4 打开200DK的样例程序时,编译报了 找不到opencv的错。。这个时候需要在宿主机环境上交叉编译opencv,但不知道如何交叉编译,还烦请专家告知。谢谢~~
  • [其他] OpenCV简介
    OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 [1]  它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。opencv是一个开源的计算机视觉开发包,这已是众所周知的了,而且越来越多的人开始研究它了。但opencv的使用者还是以高校居多,企业用得比较少,而企业使用opencv也往往是借鉴它的一些算法。计算机视觉市场巨大而且持续增长,且这方面没有标准API,如今的计算机视觉软件大概有以下三种:1、研究代码(慢,不稳定,独立并与其他库不兼容)2、耗费很高的商业化工具(比如Halcon, MATLAB+Simulink)3、依赖硬件的一些特别的解决方案(比如视频监控,制造控制系统,医疗设备)这是如今的现状,而标准的API将简化计算机视觉程序和解决方案的开发,OpenCV致力于成为这样的标准API。OpenCV致力于真实世界的实时应用,通过优化的C代码的编写对其执行速度带来了可观的提升,并且可以通过购买Intel的IPP高性能多媒体函数库(Integrated Performance Primitives)得到更快的处理速度。OpenCV与其它视觉函数库性能对比(来源百度百科)      作为开源软件,opencv的优势就是在于它有400多个免费的图像处理函数,而且涉及的面很广,从图像处理到模式识别、从静态图像到运动视频、从二维平面到相机的三维标定以及三维重建,覆盖了机器视觉的大多应用领域。它的许多算法,也是做了很好的优化的,比绝大多数教科书(当然指国内的教科书)算法优化得好。而国内的教科书,很多时候连一个算法也没讲明白过,更不用说到优化了。所以,用好opencv的开发包,就是一个不错的教材。
  • [MindX SDK] MindX 通过SendProtobuf将原始YUV/RGB图像发送给Pipeline问题
    - 使用MindX框架,通过SendProtobuf将原始YUV/RGB图像发送给Pipeline,通过mxpi_imageresize插件缩放到模型输入尺寸后进行检测流程。目前使用Opencv模拟输入原始YUV/RGB图像,但无论是YUV还是RGB都不能正常跑通或识别正确。 - 输出的图片如下所示,存在花屏和错位,不知道是Opencv转MxstDataInput存在问题,还是resize没用使用正确。 ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/23/1648023303086651621.png)
  • [其他] OpenCV 中国镜像仓库正式启用
    OpenCV 中国镜像仓:https://gitcode.net/opencvOpenCV是一个基于Apache 2.0 许可证(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、macOS、Android和iOS操作系统上。为了解决克隆 OpenCV 源码以及构建过程的下载问题,OpenCV 中国团队联系了国内一家提供代码托管服务的网站 GitCode.net,双方对 OpenCV 中国镜像的想法一拍即合,为广大 OpenCV 的开发者提供便利。这样下载就不会慢了~
  • [问题求助] atlas200dk已连接上网,但是还是Unable to locate package libopencv-dev
    已连接上网,但是还是Unable to locate package libopencv-dev
  • [其他] 使用OpenCV测量图像中物体之间的距离
    本文转自:opcv学堂本文来自光头哥哥的博客【Measuring distance between objects in an image with OpenCV】,仅做学习分享。原文链接:https://www.pyimagesearch.com/2016/04/04/measuring-distance-between-objects-in-an-image-with-opencv/已经完成了测量物体大小的任务,今天进行最后一部分:计算图片中物体之间的距离。上篇我们讨论了如何使用参考对象来测量图像中对象的大小。这个参考对象应该有两个重要的特征,包括:• 我们知道这个物体的尺寸(以英寸、毫米等表示)。• 它很容易在我们的图像中被识别出来(根据位置或外观)。给定这样一个参考对象,我们可以使用它来计算图像中对象的大小。今天,我们将结合本系列前两篇来计算对象之间的距离。计算物体之间的距离与计算图像中物体的大小算法思路非常相似——都是从参考对象开始的。我们将使用0.25美分作为我们的参考对象,它的宽度为0.955英寸。并且我们还将0.25美分总是放在图片最左侧使其容易识别。这样它就满足了我们上面提到的参考对象的两个特征。我们的目标是找到0.25美分,然后利用0.25美分的尺寸来测量0.25美分硬币与所有其他物体之间的距离。定义参考对象并计算距离打开一个新文件,将其命名为distance_between.py,插入以下代码: # import the necessary packages from scipy.spatial import distance as dist from imutils import perspective from imutils import contours import numpy as np import argparse import imutils import cv2 def midpoint(ptA, ptB): return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5) # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="path to the input image") ap.add_argument("-w", "--width", type=float, required=True, help="width of the left-most object in the image (in inches)") args = vars(ap.parse_args())# import the necessary packages我们这里的代码与上周的代码几乎相同。我们从在第2-8行上导入所需的Python包开始。 第12-17行解析命令行参数。这里我们需要两个参数:——image,它是包含我们想要测量的对象的输入图像的路径,以及——width,为我们参考对象的宽度(单位为英寸)。接下来,我们需要对图像进行预处理:# load the image, convert it to grayscale, and blur it slightly image = cv2.imread(args["image"]) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (7, 7), 0) # perform edge detection, then perform a dilation + erosion to # close gaps in between object edges edged = cv2.Canny(gray, 50, 100) edged = cv2.dilate(edged, None, iterations=1) edged = cv2.erode(edged, None, iterations=1) # find contours in the edge map cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) # sort the contours from left-to-right and, then initialize the # distance colors and reference object (cnts, _) = contours.sort_contours(cnts) colors = ((0, 0, 255), (240, 0, 159), (0, 165, 255), (255, 255, 0), (255, 0, 255)) refObj = None第2-4行从磁盘加载图像,将其转换为灰度图,然后使用7 x 7内核的高斯滤波器对其进行模糊降噪。当我们的图像被模糊后,我们应用Canny边缘检测器来检测图像中的边缘,然后进行膨胀+腐蚀来缩小边缘图中的缝隙(第7-9行)。调用cv2.findContours检测边缘图中对象的轮廓(第11-13行),而第16行从左到右对轮廓进行排序。由于我们知道0.25美分(即参考对象)将始终是图像中最左边,因此从左到右对轮廓进行排序可以确保与参考对象对应的轮廓始终是cnts列表中的第一个。然后,我们初始化用于绘制距离的colors列表以及refObj变量,该变量将存储参考对象的边界框、质心和pixels-per-metric值(看上一篇就明白pixels-per-metric的具体定义,其实就是参考对象的实际大小(单位英寸)与图片中的宽度(单位为像素)的比值)。# loop over the contours individually for c in cnts: # if the contour is not sufficiently large, ignore it if cv2.contourArea(c) < 100: continue # compute the rotated bounding box of the contour box = cv2.minAreaRect(c) box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box) box = np.array(box, dtype="int") # order the points in the contour such that they appear # in top-left, top-right, bottom-right, and bottom-left # order, then draw the outline of the rotated bounding # box box = perspective.order_points(box) # compute the center of the bounding box cX = np.average(box[:, 0]) cY = np.average(box[:, 1])xxxxxxxxxx # loop over the contours individually# loop over the contours individuallyfor c in cnts: # if the contour is not sufficiently large, ignore itif cv2.contourArea(c) < 100:continue # compute the rotated bounding box of the contourbox = cv2.minAreaRect(c)box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)box = np.array(box, dtype="int") # order the points in the contour such that they appear # in top-left, top-right, bottom-right, and bottom-left # order, then draw the outline of the rotated bounding # boxbox = perspective.order_points(box) # compute the center of the bounding boxcX = np.average(box[:, 0])cY = np.average(box[:, 1])在第2行,我们开始对cnts列表中的每个轮廓进行循环。如果轮廓比较小(第4和5行),我们认为是噪声并忽略它。 然后,第7-9行计算当前对象的最小旋转包围框。第14行上调用order_points函数(此系列第一篇定义的函数)来对矩形框四个顶点以左上角、右上角、右下角和左下角的顺序排列,我们将看到,在计算物体之间的距离时,这一点非常重要。第16行和第17行通过取边界框在x和y方向上的平均值来计算旋转后的边界框的中心(x, y)坐标。下一步是校准我们的refObj:# if this is the first contour we are examining (i.e., # the left-most contour), we presume this is the # reference object if refObj is None: # unpack the ordered bounding box, then compute the # midpoint between the top-left and top-right points, # followed by the midpoint between the top-right and # bottom-right (tl, tr, br, bl) = box (tlblX, tlblY) = midpoint(tl, bl) (trbrX, trbrY) = midpoint(tr, br) # compute the Euclidean distance between the midpoints, # then construct the reference object D = dist.euclidean((tlblX, tlblY), (trbrX, trbrY)) refObj = (box, (cX, cY), D / args["width"]) continue如果refObj为None(第4行),则需要对其进行初始化。 我们首先获取(排序后的)最小旋转边界框坐标,并分别计算四个顶点之间的中点(第10-15行)。然后计算中点之间的欧氏距离,给出我们的“像素/尺寸”比例,来确定一英寸为多少像素宽度。最后,我们将refObj实例化为一个3元组,包括:• 物体对象的最小旋转矩形对象box• 参考对象的质心。• 像素/宽度比例,我们将用其来结合物体之间的像素距离来确定物体之间的实际距离。下一个代码块负责绘制参考对象和当前检查对象的轮廓,然后定义变量refCoords和objCoords,这样(1)最小包围矩阵坐标和(2)质心的(x, y)坐标都包含在同一个数组中:# draw the contours on the image orig = image.copy() cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2) cv2.drawContours(orig, [refObj[0].astype("int")], -1, (0, 255, 0), 2) # stack the reference coordinates and the object coordinates # to include the object center refCoords = np.vstack([refObj[0], refObj[1]]) objCoords = np.vstack([box, (cX, cY)])现在我们可以开始计算图像中各个物体的质心和质心之间的距离了: # loop over the original points for ((xA, yA), (xB, yB), color) in zip(refCoords, objCoords, colors): # draw circles corresponding to the current points and # connect them with a line cv2.circle(orig, (int(xA), int(yA)), 5, color, -1) cv2.circle(orig, (int(xB), int(yB)), 5, color, -1) cv2.line(orig, (int(xA), int(yA)), (int(xB), int(yB)), color, 2) # compute the Euclidean distance between the coordinates, # and then convert the distance in pixels to distance in # units D = dist.euclidean((xA, yA), (xB, yB)) / refObj[2] (mX, mY) = midpoint((xA, yA), (xB, yB)) cv2.putText(orig, "{:.1f}in".format(D), (int(mX), int(mY - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.55, color, 2) # show the output image cv2.imshow("Image", orig) cv2.waitKey(0)在第2行,我们开始对图片中物体对象的顶点(x, y)坐标进行循环。 然后我们画一个圆表示我们正在计算距离的当前点坐标,并画一条线连接这些点(第5-7条线)。然后,第12行计算参考位置和对象位置之间的欧式距离,然后除以“像素/度量”,得到两个对象之间的实际距离(以英寸为单位)。然后在图像上标识出计算的距离(第13-15行)。距离测量结果下面是一个GIF动画,演示了我们的程序运行效果: 在每种情况下,我们的脚本都匹配左上(红色)、右上(紫色)、右下(橙色)、左下(蓝绿色)和质心(粉色)坐标,然后计算参考对象和当前对象之间的距离(以英寸为单位)。注意图像中的两个0.25美分完全平行,这意味着所有五个顶点之间的距离均为6.1英寸。下面是第二个例子,这次计算的是参考对象和药丸之间的距离: 这个例子可以作为药片分类机器人的输入,自动获取一组药片,并根据它们的大小和与药片容器的距离来组织它们。 最后一个例子计算了我们的参考对象(一张3.5英寸x 2英寸的名片)和一组7英寸的黑胶唱片和信封之间的距离:
  • [问题求助] 【Atlas300】【C++ ImageData转cv::Mat】将ImageData转cv::Mat用于opencv处理
    你好,我在Atlas300上使用AtlasVideoCapture读取网络摄像头,大致流程如下:AtlasVideoCapture* cap_;cap_ = new AtlasVideoCapture(streamName_)ImageData image;Atlas Error ret = cap_->Read(image)得到ImageData结构的image,其结构如下:struct ImageData { acldvppPixelFormat format; uint32_t width = 0; uint32_t height = 0; uint32_t alignWidth = 0; uint32_t alignHeight = 0; uint32_t size = 0; std::shared_ptr<uint8_t> data = nullptr;};接下来需要将image中的数据转为cv::Mat,该如何操作呢?
  • [其他] 使用OpenCV为视频中美女加上眼线
    计算机视觉是最令人兴奋的领域之一,其应用范围非常广泛。从医学成像到创建最有趣的面部滤镜等各个领域都充分见证了计算机视觉技术的强大。在本文中,我们将尝试创建一个人造眼线笔来模仿Snapchat或Instagram滤波器,为视频中的美女添加上美丽的眼线。最终的结果可以通过下面的动图观察到。本文介绍的内容适合想要通过计算机视觉来实现一个具有一定展示性功能的计算机视觉初学者。因此,在本文重我们会尽量简化说明,如果您对完整的程序感兴趣,可以在Github上找到完整的代码。Github的链接在本文的文末给出。 在实现本文功能之前,我们需要设置一个新的虚拟环境并安装所有必需的依赖项。这个过程比较简单,我们也在Github里面给出了如何配置环境的具体过程。在本项目中,我们需要使用的工具有OpenCV,NumPy,imutils,SciPy和Dlib。有些小伙伴可能对这些工具和库比较陌生,接下来我们简单介绍一下每个模块的作用。• OpenCV:用于图像处理的最受欢迎的模块之一。我们将使用OpenCV读取,写入和绘制图像。• NumPy:在处理OpenCV项目时经常使用NumPy。图像本质上是一个像素数组,OpenCV使用以NumPy数组形式存储的这些数组,并对图像执行操作。• Imutils:Imutils附带了自定义功能,使我们的计算机视觉工作变得更加轻松。在这里,我们将使用它来将dlib对象转换为非常灵活且广泛接受的numpy数组。• Scipy:顾名思义,SciPy用于python上的科学计算。我们将使用它来创建插值(如果现在没有意义,可以的)。• Dlib:Dlib是一个包含各种ML算法的C ++库。我们将使用dlib提取面部界标点。项目简要介绍该程序首先从每个面孔中提取68个界标点。在这68个点中,点37–42属于左眼,点43–48属于右眼,具体形式如下图所示。因为我们的目标是给面部添加眼线,所以我们只对37-48点感兴趣,因此我们提取了这些点。我们将对这些提取的点进行插值。插值意味着我们尝试在两个给定点之间插入点。我们可以使用的插值方式如下图所示。眼线算法的流程图如下所示接下来,我们将进一步详细描述该算法。如果小伙伴只对运行代码感兴趣,可以跳至最后一部分。算法介绍我们首先需要提取脸部周围边界框的坐标。OpenCV将图像转换为NumPy数组。numpy.array(即图像的矩阵表示形式)存储在名为的变量中frame。我们使用一个名为face_detector()的函数,该函数返回围绕框架中所有脸部的包围框的坐标。这些边界框坐标存储在一个名为bounding_boxes的变量中。遍历循环bounding_boxes以将眼线应用于帧中检测到的每个脸部。face_landmark_points存储68个坐标点。eye_landmark_points是从getEyeLandmarkPts()函数中得到。getEyeLandmarkPts()函数使用68个坐标点作为输入并返回具有左上眼睑的坐标4个矩阵,左上眼线(L_eye_top),左下眼线(L_eye_bottom)和相同的右眼(R_eye_top & R_eye_bottom)。这可以通过简单的NumPy索引完成的。我们将端点(pt号37、40、43和46。请参见68个界标点图)向外移动5px,以使外观更逼真。现在,我们需要对这些点进行插值以获得平滑的曲线,进而可以画出眼线。我们需要对每个曲线进行不同的处理(即L_eye_top,L_eye_bottom,R_eye_top,R_eye_bottom)。因此,我们为每个曲线使用单独的变量名称。interpolateCoordinates()用于在每条曲线上生成插值。重复使用该函数,为每个曲线生成插值坐标。这个函数为每个曲线返回一个插值点数组。drawEyeLiner()函数将生成的插值点作为参数,并在两个连续点之间画一条线。在两个循环中为每个曲线完成此操作,一个循环用于左眼,另一个循环用于右眼。 调用项目该项目的用发非常简单,首先从Github上克隆到本地 git clone https://github.com/kaushil24/Artificial-Eyeliner/接下来,打开命令提示符并键入以下代码以运行示例测试python3 eyeliner.py -v "Media/Sample Video.mp4"我们也可以通过将视频路径放在参数中来使用自己的视频。完整的CLI命令如下:python eyeliner.py [-i image] [-v video] [-d dat] [-t thickness] [-c color] [-s save]每个参数的具体含义如下:• i :要在其上绘制眼线的图像的路径• v :要在其上绘制眼线的视频的路径。• v :也可以通过网络摄像头获取视频。例如:python3 -v webcam -s "Webcam output"• t :整数(整数)以设置眼线的厚度。默认值= 2。推荐的数值介于1-5之间• d:shape_predictor_68_face_landmarks.dat文件的路径。默认路径在根目录中。除非将shape_predictor_68_face_landmarks.dat文件存储在其他位置,否则不需要使用此参数。• c :更改眼线的颜色。语法-c 255 255 255。默认值= 0 0 0。其中每个数字代表其RGB值。• s :要将输出保存到的位置和文件名。注意程序在保存文件时会自动添加扩展名。如果已经存在同名文件,它将覆盖该文件。转载自小白学视觉公众号
总条数:322 到第
上滑加载中