图形视频

180709 利用Python与OpenCV裁剪图像做数据增强

原始图像 裁剪图像 # -*- coding: utf-8 -*- """ Created on Mon Jul 9 11:38:19 2018 @author: guokai_liu """ import numpy as np import matplotlib.pyplot as plt import cv2 filename = 'Yuna2.jpg' def crop_figure(fn,kw=100,kh=100,sx=50,sy=50): # assgn saving name sn = fn.split('.')[0] # read image img = cv2.imread(fn) # set parameters f_h, f_w,f_c = img.shape k_w = kw k_h = kh s_x = sx s_y = sy # get output numbers of rows and columns n_y = (f_h-k_w)//s_y n_x = (f_w-k_h)//s_x # begin points for rows and columns c_x = [i+s_x*i for i in range(n_x)] c_y = [i+s_y*i for i in range(n_y)] # crop images for idx_y, y in enumerate(c_y): for idx_x,x in enumerate(c_x): crop_img = img[y:y+k_h,x:x+k_w] cv2.

Ubuntu16.04+cuda8.0+cudnn5.1+anaconda+tensorflow0.12.1暗影精灵三GTX1080ti

电脑配置:i7-8700K 16G 256GSSD+2T GTX1080Ti 由于要用tf==0.12.1,所以配置的深度学习环境并不是最新的。想安装最新的TF可以参考此教程 1、win10+Ubuntu16.04双系统,安装教程、补充教程。 2、cuda8.0+cudnn5.1+anaconda 安装教程,建议从作者提供的百度云链接下载,英伟达官网链接有点慢。 注:安装英伟达的驱动,桌面>>系统设置>>软件和更新>>附加驱动>>选择英伟达的驱动。 注:cuda的例子没有下载,所以教程中没有make例子。 3、用anaconda安装TF,参照tensorflow官网 conda create -n tensorflow ##后面加 pip python=2.7 (or 3.X) #Activate the conda environment by issuing the following command: source activate tensorflow (tensorflow)$ # Your prompt should change (tensorflow)$ pip install --ignore-installed --upgrade \ tfBinaryURL ##轮子地址 也可以直接 pip install tensorflow-gpu==0.12.1 激活conda环境后,进入python 检验TF和cuda是否安装成功 # Python import tensorflow as tf hello = tf.constant('Hello, TensorFlow!') sess = tf.Session() print(sess.run(hello)) 我的一开始报错, I tensorflow/stream_executor/dso_loader.cc:119]Could’t open CUDA library libcudnn.

OpenCV实验系列之修改图片对比度与亮度

OpenCV实验系列之修改图片对比度与明亮度 注意:以下内容根据opencv官网提供的教程结合个人理解所得,仅是个人学习笔记,可能存在错误或偏差,欢迎指正。 OpenCV实验系列之修改图片对比度与明亮度 对比度与亮度的理解个人臆测 实现方法 对比度与亮度的理解(个人臆测) 以下对于对比度的解释来自百度百科 对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。但对比率遭受和亮度相同的困境,现今尚无一套有效又公正的标准来衡量对比率,所以最好的辨识方式还是依靠使用者眼睛。 以灰度图来举例,个人理解就是图片中亮与暗点间的灰度差值,比如255与200的对比度小于255与100的对比度,对于灰度图来说亮度就是整体的白的程度。由此可以得出对对比度和亮度进行调节的公式: α用来控制对比度,β用来控制亮度。可以想象当α>1是图片的对比度将扩大(扩大了像素点间的差异),β>0时亮度将提高,当0<α<1是图片的对比度将j减小,β<0时亮度将减小。 实现方法 可以使用LUT() http://blog.csdn.net/Nrush/article/details/79330077 进行处理在下例中使用一般遍历的方法进行处理。 #include #include #include #include using namespace std; using namespace cv; void main() { double alpha = 1.5; double beta = 0; Mat src; src = imread( "timg.jpg" ); imshow("src",src); Mat dst = Mat::zeros( src.size(), src.type()); for( int y = 0; y < src.rows; y++ ) { for( int x = 0; x < src.cols; x++ ) { for( int c = 0; c < 3; c++ ) { dst.

图像增强:多尺度的图像细节提升(multi-scale detail boosting)实现方法

图像增强:多尺度的图像细节提升(multi-scale detail boosting)实现方法 看到一篇博客介绍基于多尺度的图像的细节提升算法,其参考论文《Dark image enhancement based onpairwise target contrast and multi-scale detail boosting》,下图是该论文的核心算法过程。然后自己在Matlab和OpenCV实现了该算法,最终实现的效果还是不错的,可以增强图像的细节部分。 论文的核心算法过程: 论文的核心思想类似于Retinex,使用了三个尺度的高斯模糊,再和原图做减法,获得不同程度的细节信息,然后通过一定的组合方式把这些细节信息融合到原图中,从而得到加强原图信息的能力:请参考这一篇博客介绍:http://www.cnblogs.com/Imageshop/p/7895008.html,该博客给出了SSE的实现过程。 算法实现很容易,下面,我给出本人的OpenCV和Matlab实现方法: OpenCV实现方法: #include #include #include using namespace std; using namespace cv; cv::Mat multiScaleSharpen(cv::Mat Src, int Radius) { int rows = Src.rows; int cols = Src.cols; int cha = Src.channels(); cv::Mat B1, B2, B3; GaussianBlur(Src, B1, Size(Radius, Radius), 1.0, 1.0);//高斯模糊 GaussianBlur(Src, B2, Size(Radius*2-1, Radius*2-1), 2.0, 2.0); GaussianBlur(Src, B3, Size(Radius*4-1, Radius*4-1), 4.0, 4.0); double w1 = 0.

openCV学习笔记(七):傅里叶变换

之前熟悉了openCV怎么调整图片对比度和亮度(通过线性和非线性的方法),都是很基础的图形操作,这边开始介绍openCV图像处理很重要的工具方法:傅里叶变换。 这部分内容涉及到复杂的傅里叶公式、也涉及到很多数学上的原理,单单通过官网是根本不会理解这部分内容的,我也是翻阅了很多的资料才对这部分内容有了比较清晰的了解,这边我通过用openCV的傅里叶变换方法实现图片校正的功能,里面涉及到的方法和原理我尽量详细的介绍。 上一篇内容:http://blog.csdn.net/jbl20078/article/details/78854660 openCV 傅里叶变换实际应用:图像旋转校正 第一部分:什么是傅里叶变换 光是学习傅里叶变换就花了我多半天的时间,后悔大学没好好学呀,这部分内容如果想深入了解的话看这个神人写的吧,已经非常用心并且很耐看: http://blog.jobbole.com/70549/ 如果对傅里叶变换还模糊或者看不下去的话也没关系,我们了解它在图形处理方面的意义和能处理什么问题就可以了。 第二部分:傅里叶变换在图形处理方面的实际意义和应用 如果第一部分详读了之后,应该会清楚傅里叶变换后其实是描述频率的二维数据,有了可以描述图像的频率(或者波频)我们能分辨出图像的高频部分和低频部分,高频部分就是图像对比度很大的区域(高频点趋近白色),低频部分是图像对比度比较小的部分(低频趋近于暗色),图像的边缘通常就是高频,因为这个区域色差普遍很大,所以傅里叶变换后的图像数据会比较方便的处理边缘(为我们边缘检测和图片方向检测提供了可能),如果你了解图像噪音的话(由于图像的传输等原因,图像中会有噪点)傅里叶通过对频率值的分析可以去除图像噪音,达到增强图像的效果。 当然,傅里叶应用的地方还有很多,比如图像特征值提取等,正是由于它的用途这么大,我们才一定要花大力气搞懂它的使用方法和原理,对我们后面图形的处理会有极大的帮助。 下面是傅里叶变换得到的波谱图(或者叫频率图,幅度图,无所谓,我们知道它是描述图形变化频率的数据就ok了)。 后面我会介绍怎么通过傅里叶变换后的波频图来给上面的图片扶正。 第三部分:实现图片的傅里叶变换 傅里叶变换需要经历很多步骤,我们分解一步步来实现: 1、读取原始图形数据,并将图像转化成灰度图(因为彩色图很多数据对我们没用,灰度值就够了,而且计算量小) Mat mat = [[CVUtil sharedHelper]cvMatFromUIImage:_buildImg.image]; Mat grayImg; cvtColor(mat, grayImg, COLOR_BGR2GRAY); 我读取图形的方式跟官网不同,因为我是在IOS系统上模拟测试的,这个根据自己测试的平台来修改 2、扩充灰度图的尺寸并且填充像素(图形尺寸是2,3,5倍数的时候傅里叶变换计算速度最快),这些接口openCV都提供了 Mat padded; int m = getOptimalDFTSize(grayImg.rows); int n = getOptimalDFTSize(grayImg.cols); //通过copyMakeBorder进行填充像素和颜色(多出的像素点全部用0填充) copyMakeBorder(grayImg, padded, 0, m-grayImg.rows, 0, n-grayImg.cols, BORDER_CONSTANT, Scalar::all(0)); 这部分涉及到的接口都很简单,看参数都能明白是做什么,如果不清楚,调到代码中看方法描述,或者去下载源码阅读。 3、扩充图形的通道,准备调用离散傅里叶变换方法 看了第一部分内容或者了解傅里叶变换公式的同学知道,傅里叶变换得到的结果是一个复数,实数和虚数部分为了都能保存到我们傅里叶变换后的结果,我们要给上面的灰度图 扩充一个值全部为0的通道,并且把数值转化成float类型。最后得到的傅里叶变换结果我们会将实数部分和虚数部分拿出来计算幅度值(就是我们想要得到的频率图)做后面的校正 图形,下面会说。 //傅里叶变化后的结果是一个复数,也就是转化到频域中会有两个图像值,我们将图像转化成float类型 并且添加一个额外通道来存储复数部分 Mat planes[] = {Mat_(padded),Mat::zeros(padded.size(), CV_32F)}; //复制了一个padded,然后添加了一个全是0的通道 Mat complex; //进行通道的混合 //merge函数是合并多个array 成为一个多通道的array,比方说array1 array2 合并成array3 那么array3[1][0] = array1[1] //array3[1][2] = array2[1] 它的逆向操作是split方法 merge(planes,2,complex); //合并好了 相当于给傅里叶变换的结果预先分配了存储空间(因为结果是复数)所以下面就可以进行傅里叶变换了 //dft函数(离散傅里叶变换) //输入输出支持同一个图像 dft(complex,complex); 4、计算幅度图,得到频域图谱 傅里叶计算结束,我们得到了一个双通道的Mat数据,第一个通道是傅里叶变换数据的实数,第二个通道是傅里叶变换数据的虚数,这两者具体几何意义是什么,第一部分的连接 文章都有讲,不清楚的小伙伴可以回头看下,或者我们清楚下面的概念: 我们一般用幅度图像来标识图像傅里叶的变换结果,幅度的计算公式: Re(DFT)是实数,IM(DFT)是虚数

openCV学习笔记 (六) : 改变图像的对比度和亮度

上一篇熟悉了filter2D函数,通过掩码矩阵实现滤波功能(锐化图片),这里继续熟悉其他处理图像的方式:改变图像对比度和亮度。 注意: 如果连续关注我笔记的同学会发现,这里我跳过了官网核心模块中的两部分内容(只是没有做总结):一个是图形的基本操作(Load、write,以及像素点获取的方式),一个是图片的线性混合。希望跟我一样学习的同学最好按照步骤去熟悉这两部分内容,openCV官网的教程安排还是很合理的,基础部分经常会在后面章节中用到。 上一篇:openCV实现滤波功能:http://blog.csdn.net/jbl20078/article/details/78852194 官网地址:https://docs.opencv.org/master/d3/dc1/tutorial_basic_linear_transform.html 调整图像的对比度和亮度(通过线性方法) 一提到线性方法我们第一时间应该会联想到:二元一次方程 这里openCV介绍的一个函数方法就是利用二元一次方程线性修改图像中的像素值 这种算子能够调整图片亮度和对比度,当然也可以分区域的设置,这个后面用到再说,直接看源码的实现: void convertToImage(Mat& mat,Mat outputMat,double alpha,int beta){ //遍历这个mat for(int i = 0 ; i < mat.rows;i++){ for(int j = 0 ; j < mat.cols; j++){ for(int c = 0; c < 3; c++){ outputMat.at(i,j)[c] = saturate_cast(alpha*(mat.at(i,j)[c])+beta); } } } } 源码很简单,openCV提供给我们的实现函数式Mat.convertTo(OutputArray m , int rtype, double alpha = 1, double beta = 0); 参数说明下: outputArray就是输出的目标Mat rtype是深度,和之前用到的filter2D函数一样,-1代表使用跟源一样的depth,或者填写image.depth() alpha就是α beta就是β (后面还会介绍γ方法) 使用方法: //先创建一个outputmat Mat outputMat = Mat::zeros(oriMat.

【PhotoShop】用自己的照片做个好看的星空头像PS

图片素材均来自于网络。 1.打开图像,把图片直接拖入ps 2.选择 多边形套索 工具 3.圈出想要的部分 4.图像 》》调整 》》阈 (yu四声) 值 5.调整小三角,直到看清五官(我这个素材选择有点不太好,有点形成阴阳脸,就是说 明暗差距有点大,调出来也是一面黑一面白。只能看清楚一边。) 6.调整好之后,点击确定。然后按Ctrl+J 把这部分烤出来。 7.点击 选择》》色彩范围》》吸取头发黑色的部分颜色(这时候对话框里的脸会变黑。) 8.点击确定。Ctrl+N 新建一个页面。参数自定就行。我这里的参数有点大。分辨率尽量是72 9.这一步可以跳过,这一步的目的只是为了让之后的结果看得更加清楚。右击新建的图层前面的缩略图,选择图层样式,把图层样式改为如下参数。 10.点击回到刚才的选项卡,按“V”字母键,切换到移动工具,把我们的“脸”拖到第二个选项卡(新建的页面) 拖过来 是这样的 11.把之前准备好的星空素材拖进来。。星空素材的图层应该在 “脸”图层之上。 12.(这一步很关键)按住Alt,把鼠标移动到 星空和“脸”中间,会出现如图空白处绘制的形状,然后单击鼠标左键。 13.把可能多余的部分用左侧橡皮擦工具擦掉,如果嫌麻烦,那你前期就应该仔细吧脸部裁出来。 14.如果想在下面打上字。同样的操作方法。打完字以后,再拖进来一张“星空”,星空图层在字的上面,按住Alt并且单击鼠标左键(位置在星空图层和字图层的中间),就ok啦! 效果如图: 15.最终出来的图片如图。 挚谢阅读。

JavaFx+openCv项目在win7系统部署异常(no opencv_java310 in java.library.path)

【学习参考】 JavaFx+openCv项目代码参考官网教程点击跳转 JavaFx项目部署参考点击跳转 【问题解决】 以上是学习的参考,实际操作部署后,运行exe文件会出现两个错误弹窗: Error invoking method! Failed to launch jvm! .exe程序无法执行。 根据网上的找的半自动解决方法【直接执行jar包看异常】,出现以下异常内容。 java.lang.reflect.InvocationTargetException <省略部分异常> Caused by: java.lang.UnsatisfiedLinkError: no opencv_java310 in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at application.Main.main(Unknown Source) ... 11 more Exception running application application.Main 然后根据java.lang.UnsatisfiedLinkError: no opencv_java310 in java.library.path继续查找问题,看了多个解决方法后,明白问题的来源是程序中System.loadLibrary(Core.NATIVE_LIBRARY_NAME);加载不到opencv_java310.dll,而我用eclipse调试时因为按照教程对该参数进行设置过了,所以没有报错,但是部署的文件并不能获取到该参数,因此异常。所以对该加载opencv_java310.dll程序进行修改即可。修改如下:(两种方法,选其一即可) 相对路径方法 第一步: System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 修改为: String relativelyPath=System.getProperty("user.dir"); System.load(relativelyPath+"\\opencv_java310.dll"); 第二步: 部署安装,但还是会报错 第三步: 找到部署的文件安装位置,默认C:\Users\[用户名]\AppData\Local\[项目名],然后打开其下的app文件夹,将opencv_java310.dll拷贝到这里。 执行上层文件夹中的exe文件即可正常运行,无报错。 绝对路径方法: System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 修改为: System.load("E:\\opencv\\build\\java\\x64\\opencv_java310.dll"); 以上路径根据你的opencv_java310.dll实际位置修改。 重新打包部署,然后执行无报错。

Opencv 分水岭算法用于图像分割

目标 • 使用分水岭算法基于掩模的图像分割 • 学习函数: cv2.watershed() 原理 任何一幅灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷。我们向每一个山谷中灌不同颜色的水,随着水的位的升高,不同山谷的水就会相遇汇合,为了防止不同山谷的水汇合,我们需要在水汇合的地方构建起堤坝。不停的灌水,不停的构建堤坝直到所有的山峰都被水淹没。我们构建好的堤坝就是对图像的分割。这就是分水岭算法的背后哲理。 但是这种方法通常都会得到过度分割的结果,这是由噪声或者图像中其他不规律的因素造成的。为了减少这种影响, OpenCV 采用了基于掩模的分水岭算法,在这种算法中我们要设置哪些山谷点会汇合,哪些不会,这是一种交互式的图像分割。我们要做的就是给我们已知的对象打上不同的标签。如果某个 区域肯定是前景或对象,就使用某个颜色(或灰度值)标签标记它。如果某个区域肯定不是对象而是背景就使用另外一个颜色标签标记。而剩下的不能确定是前景还是背景的区域就用 0 标记。这就是我们的标签。然后实施分水岭算法。每一次灌水,我们的标签就会被更新,当两个不同颜色的标签相遇时就构建堤 坝,直到将所有山峰淹没,最后我们得到的边界对象(堤坝)的值为 -1。 代码 下面的例子中我们将就和距离变换和分水岭算法对紧挨在一起的对象进行分割。 如下图所示,这些硬币紧挨在一起。就算你使用阈值操作,它们任然是紧挨着的。 我们从找到这些硬币的近似估计值开始,我们使用Otsu’s二值化。 import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('image/coins.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) 结果图: 现在我们要去除图像中的所有的白噪声,这就需要使用形态学中的开运算。为了去除对象上小的空洞我们需要使用形态学闭运算。所以我们现在知道靠近对象中心的区域肯定是前景,而远离对象中心的区域肯定是背景。而不能确定的区域就是硬币之间的边界。 所以我们要提取肯定是硬币的区域。腐蚀操作可以去除边缘像素。剩下就可以肯定是硬币了。当硬币之间没有接触时,这种操作是有效的。但是由于硬币之间是相互接触的,我们就有了另外一个更好的选择:距离变换再加上合适的阈值。接下来我们要找到肯定不是硬币的区域。这是就需要进行膨胀操作了。膨胀可以将对象的边界延伸到背景中去。这样由于边界区域被去处理,我们就可以知道那些区域肯定是前景,那些肯定是背景。 剩下的区域就是我们不知道该如何区分的了。这就是分水岭算法要做的。这些区域通常是前景与背景的交界处(或者两个前景的交界)。我们称之为边界。从肯定是不是背景的区域中减去肯定是前景的区域就得到了边界区域。 kernel = np.ones((3,3),np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations= 2) sure_bg = cv2.dilate(opening, kernel,iterations=3) dist_transform =cv2.distanceTransform(opening, 1, 5) ret,sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0) sure_fg = np.

OpenGL开启Gouraud明暗处理,减少马赫夫效应

在我们建立三维模型的过程中,当用多边形网格或者是三角面片来近似的表示曲面的表面时,曲面被离散成许多的平面多边形,如果我们的网格较大,离散度较粗,在模型表面使用明暗处理后,两两相邻的多边形会出现凸起或者是凹陷的折痕,在连接处显得比周围处亮或者暗,这就是所谓的马赫夫效应,如下图所示 针对于出现的马赫夫效应,我们需要进行明暗处理,消除或者是减少三维模型的马赫夫效应,使其看上去更加的光滑美观,常用的明暗处理技术有双线性光强插值—Gouraud明暗处理技术和双线性法向插值-Phong明暗处理技术。以下展示经过明暗处理前后结果对比 OpenGL提供了两种着色模式void glShadeModel ( GLenum mode),恒定着色GL_FLAT,光滑着色GL_SMOOTH,而GL_SMOOTH中则是使用了Gouraud明暗处理技术,对于Phong明暗处理技术可以参见http://blog.csdn.net/dalewzm/article/details/46291397 http://blog.csdn.net/silangquan/article/details/10011169 Gouraud明暗处理算法在处理亮度的不连续性方面很有效,但是在明暗强度函数的斜率急剧变化处仍然可以看到马赫夫效应,不能完全消除光强度的不连续性。而Phong明暗处理是对表面的法向量而不是亮度进行插值,大大改善了Gouraud模型对高亮度镜面反射光的处理,在每一点都是用法向量的一个近似值,所以一般法向量插值的结果要优于亮度插值,在很大程度上消除了马赫夫效应,但是会大大增加明暗处理的时间。 鉴于此,我在用MC算法建立三维模型的时候,由于我的网格设置较大,导致出现了马赫夫效应,即模型表面的可视化效果不光滑,如下: 于是使用OpenGL自带的Gouraud明暗处理技术,以一个MC算法生成的章鱼模型为例子,效果如下 相比未使用明暗处理的模型,使用了Gouraud处理的模型从可视化的角度上来看更加的光滑,效果更好。