精华内容
下载资源
问答
  • 一、前言 省略了相机的内外参数标定,默认相机没有畸变,对如下场景进行视觉定位。 场景设定如下: 1、相机镜头垂直水平面固定,也就是说本场景...不论是二维平面定位还是三维空间定位,目的都是想要获取目标...

    一、前言

    省略了相机的内外参数标定,默认相机没有畸变,对如下场景进行视觉定位。

    场景设定如下:

    1、相机镜头垂直水平面固定,也就是说本场景只能进行二维平面的定位补偿,默认Z轴坐标等于0;

    2、相机完成标定,即像素坐标能够转换为世界坐标;

    3、靶标是如图的一张白纸,白纸上有一个黑色圆形和一个黑色三角形;

    定位补偿的想法:

    不论是二维平面定位还是三维空间定位,目的都是想要获取目标的位置信息,而位置信息不仅包含了x,y,z=0,还包含旋转角度。当然,在二维平面中旋转角度只有一个,在三维空间中旋转角度有三个。

    1、设定模板:

    也就是在之前我们设定的场景中,把靶标放在你想放的位置上,然后拍一张照。假设就是上图所示。

    因为我们已经建立了像素坐标系,以图像的左上角为原点。所以,进行图像处理得到黑色圆的质点坐标X_coordinate=[x0,y0](名字无所谓),这个坐标就是模板坐标。当然为了简单,我们设定模板的时候,最好让向量AB能够和X轴平行且方向相同,因为这样的话AB向量和X轴的夹角就是0°,默认为靶标没有发生旋转。

    2、计算偏移量:

    当模板坐标确定后,如果靶标发生偏移,则再次识别圆,确定圆的质点坐标[x1,y1]。则相对模板靶标的偏移量就是[x1-x0,y1-y0]。

    3、计算旋转角度:

    知道了坐标的偏移量还不行啊,因为我们不知道靶标往那个方向偏移了,所以要确定靶标相对模板的旋转角度。

    在x轴上任意取一点[112,0],与原点[0,0],可以构成一个向量X_Particle = np.array([112,0])。然后找到圆的质点和三角形的质点,求出AB向量。最后根据向量夹角的公式就能算出旋转角度。

    注意:向量的夹角范围是0到180,所以要根据向量AB的方向来判断。这里我判断如果向量AB的方向和Y轴方向一致,则夹角为正;否则夹角为否。

    二、完整代码

    import cv2
    import numpy as np
    
    
    #定义线程函数——
    def PositionParticle(frame):
        gauss_img = cv2.GaussianBlur(frame,(3,3),0)
        gray_img = cv2.cvtColor(gauss_img,cv2.COLOR_RGB2GRAY)
        _,er_img = cv2.threshold(gray_img,90,255,cv2.THRESH_BINARY_INV)
        cv2.imshow('er',er_img)
        #提取轮廓
        contours,_ = cv2.findContours(er_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        #提取质点
        Particle = []
        for contour in contours:
            contour_ = np.squeeze(contour)
            x = np.int(np.sum(contour_,axis=0)[0] / len(contour_))
            y = np.int(np.sum(contour_,axis=0)[1] / len(contour_))
            Particle.append([x,y])
        #debug
        print(Particle)
    
        #霍夫圆检测——找到图像中的圆——鲁棒性真差
        circles = cv2.HoughCircles(gray_img,cv2.HOUGH_GRADIENT,1,10,param1=100,param2=35)
        #debug
        print(circles)
        ######################求方向向量###鲁棒性差#############
        Particle = np.array(Particle)
        #定义方向向量的起始点A和终止点B
        A,B = [],[]
        for circle in circles[0,:]:
            i = np.array(circle[:2])
            for j in Particle:
                #判断已求质心中,那个是圆的——是圆的就赋值给A点
                if np.abs(np.sum(j-i)) < 5:
                    B = j
                else:
                    A = j
        Poisiton = np.array(B) - np.array(A)
        return Poisiton,B
    #坐标域判断函数
    def Coordinate(x_particle,mark_particle):
        if mark_particle[1] >= 0:
            angle = np.arccos(x_particle.dot(mark_particle) /
                              (np.sqrt(x_particle.dot(x_particle)) * np.sqrt(mark_particle.dot(mark_particle)))) * 180 / np.pi
        else:
            angle = np.arccos(x_particle.dot(mark_particle) /
                              (np.sqrt(x_particle.dot(x_particle)) * np.sqrt(mark_particle.dot(mark_particle)))) * (-180) / np.pi
        return angle
    
    
    
    if __name__ == '__main__':
        #定义一个X轴的方向向量
        X_Particle = np.array([112,2])
        #定义模板坐标
        X_coordinate = np.array([285,85])
        #debug
        print(X_Particle)
        video = cv2.VideoCapture(1)
        while video.isOpened():
            ok,frame = video.read()
            if not ok:
                print('video open error')
                break
            else:
                cv2.imshow('src',frame)
                key = cv2.waitKey(5)
                #定义键盘事件
                if key & 0XFF == 27:    #Esc事件
                    break
                if key & 0XFF == 32:    #Space事件
                    Mark_Particle,Circle = PositionParticle(frame)
                    #debug
                    print(Mark_Particle)
                    #角度偏差
                    angle = Coordinate(X_Particle,Mark_Particle)
                    print(angle)
                    #坐标偏差
                    lass = Circle - X_coordinate
                    print(lass)
    
    
        cv2.destroyAllWindows()
    

    三、代码解释

    首先说明,代码能够运行,但是这就是一个练手的demo,不要期望精度有多高。另外,圆的识别也是一个问题,每次圆的质点坐标都有1到2个像素的偏差。

    在PositionParticle(frame)函数中,先使用轮廓提取图像中的圆和三角形最外层轮廓;根据每一个轮廓的点,能求出轮廓对应的质点,但是不能确定那个是圆的质点,那个是三角形的质点。所以在进行霍夫圆检测(如果识别不到圆,就把param2参数设小点),然后让两个质点分别和检测出的圆心做距离比较(距离可以设置为圆半径的五分之一),距离越小的应该就是圆的质点;最后就能求得AB向量。

    函数Coordinate(x_particle,mark_particle),使用mark_particle[1]判断就是AB向量的y值,当mark_particle[1]大于等于0时,AB向量和x轴夹角就是正的;当其小于0时,AB向量和x轴夹角就是否的。

    展开全文
  • 一种C语言创建超大二维数组的办法

    千次阅读 2018-11-17 15:43:39
    最近需要写一套JNI来纪录整个屏幕的像素信息(9屏截屏),于是想创建一个二维数组方便快捷地进行保存,结果炸开了: 基本可以百分百肯定栈空间不足,但我又不想增加栈空间,那怎么办呢?其实还是有办法的。 ...

     

     

    最近需要写一套JNI来纪录整个屏幕的像素信息(9屏截屏),于是想创建一个二维数组方便快捷地进行保存,结果炸开了:

    基本可以百分百肯定是栈空间不足,但我又不想增加栈空间,那怎么办呢?其实还是有办法的。

    首先二维数组是什么呢?其实就是两部分组成,一个一维指针数组,然后数组里面的每个指针指向(保存)了一个唯一对应的定长数组的首地址而已。(同理,三维数组,就是三部分组成,第一部分是指向一堆等长一维指针数组的指针,第二部分是这些指针指向的一维指针数组,第三部分就是数组),如图:

    一维数组:

    二维数组:

    三维数组:

     

    好的,道理我们懂了,那么怎么做呢?既然一次创建会爆炸,那我们可以分步创建的啦:

    1、第一步,以int二维数组为例,以宽度(或高度)创建专门装int数组头地址int*指针数组

    2、第二步,以宽度(或高度)遍历刚刚的int*地址数组,给每个地址数组创建一个高度(或宽度)为大小的int数组空间,并把空间头地址给予int*地址数组对应的位置。

    效果如下,顺利运行。

    写这个例子的时候遗漏了free掉申请的堆内存,记得free,不然会内存泄漏

     

    展开全文
  • 在工业中经常要检测一个零件的尺寸,但是图像处理得到的...很多商业软件都没有二维标定的功能,只有三维标定,因此本DEMO还是很有用武之地的。 附图如下: 转载于:https://www.cnblogs.com/chita/p/3645793.html...

    在工业中经常要检测一个零件的尺寸,但是图像处理得到的是像素值,怎么才能得到实际的毫米值呢?这就要用到二维标定,我用OPENCV写了一个利用标定板进行标定的DEMO。

    很多商业软件都没有二维标定的功能,只有三维标定,因此本DEMO还是很有用武之地的。

    附图如下:

    转载于:https://www.cnblogs.com/chita/p/3645793.html

    展开全文
  • 、实现三维混合  进行三维场景的混合时必须注意的,那就是深度缓冲。  深度缓冲这样一段数据,它记录每一个像素距离观察者有多近。在启用深度缓冲测试的情况下,如果将要绘制的像素比原来的像素更近,则像素...

    先学习OpenGL-入门-二维混合
    二、实现三维混合
      进行三维场景的混合时必须注意的,那就是深度缓冲。
      深度缓冲是这样一段数据,它记录每一个像素距离观察者有多近。在启用深度缓冲测试的情况下,如果将要绘制的像素比原来的像素更近,则像素将被绘制。否则,像素就会被忽略掉,不进行绘制。这在绘制不透明的物体时非常有用—— 不管是先绘制近的物体再绘制远的物体,还是先绘制远的物体再绘制近的物体,或者干脆以混乱的顺序进行绘制,最后的显示结果总是近的物体遮住远的物体。
       然而在你需要实现半透明效果时,发现一切都不是那么美好了。如果你绘制了一个近距离的半透明物体,则它在深度缓冲区内保留了一些信息,使得远处的物体将无法再被绘制出来。虽然半透明的物体仍然半透明,但透过它看到的却不是正确的内容了。
       要解决以上问题,需要在绘制半透明物体时将深度缓冲区设置为只读,这样一来,虽然半透明物体被绘制上去了,深度缓冲区还保持在原来的状态。如果再有一个物体出现在半透明物体之后,在不透明物体之前,则它也可以被绘制(因为此时深度缓冲区中记录的是那个不透明物体的深度)。以后再要绘制不透明物体时,只需要再将深度缓冲区设置为可读可写的形式即可。
      绘制一个一部分半透明一部分不透明的物体,需要把物体分为两个部分, 一部分全是半透明的,一部分全是不透明的,分别绘制就可以了。 即使使用了以上技巧,我们仍然不能随心所欲的按照混乱顺序来进行绘制。必须是先绘制不透明的物体,然后绘制透明的物体。
      否则,假设背景为蓝色,近处一块红色玻璃,中间一个绿色物体。如果先绘制红色半透明玻璃的话,它先和蓝 色背景进行混合,则以后绘制中间的绿色物体时,想单独与红色玻璃混合已经不能实现了。
       总结起来,绘制顺序就是:**首先绘制所有不透明的物体。**如果两个物体都是不透明的,则谁先谁后都没有关系。**然后,将深度缓冲区设置为只读。接下来,绘制所有半透明的物体。**如果两个物体都是半透明的,则谁先谁后只需要根据自己的意愿(注意了,先绘制的将成为“目标颜色”,后绘制的将成为“源颜色”,所以绘制的顺序将会对结果造成一些影响)。 最后,将深度缓冲区设置为可读可写形式。 调用glDepthMask(GL_FALSE);可将深度缓冲区设置为只读形式。调用glDepthMask(GL_TRUE);可将深度缓冲区设置为可 读可写形式。
                           
       那么,实际的演示一下吧。我们来绘制一些半透明和不透明的球体。假设有三个球体,一个红色不透明的,一个绿色半透明的,一个蓝色半透明的。红色最远,绿色在中间,蓝色最近。根据前面所讲述的内容,红色不透明球体必须首先绘制,而绿色和蓝色则可以随意修改顺序。这里为了演示不注意设置深度缓冲的危害,我们故意先绘制最近的蓝色球体,再绘制绿色球 体。 为了让这些球体有一点立体感,我们使用光照。在(1, 1, -1)处设置一个白色的光源。代码如下:

    // 三维混合.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include "pch.h"
    #include <GL/glut.h>
    #include <iostream>
    
    GLfloat angle = 0.0f;
    
    //设置白色光源
    void setLight(void)
    {
    	static const GLfloat light_position[] = { 1.0f,1.0f,-1.0f,1.0f };
    	static const GLfloat light_ambient[] = { 0.2f,0.2f,0.2f,1.0f };
    	static const GLfloat light_diffuse[] = { 1.0f,1.0f,1.0f,1.0f };
    	static const GLfloat light_specular[] = { 1.0f,1.0f,1.0f,1.0f };
    
    	glLightfv(GL_LIGHT0, GL_POSITION,light_position);
    	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    	glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
    
    	glEnable(GL_LIGHT0);
    	glEnable(GL_LIGHTING);
    	glEnable(GL_DEPTH_TEST);
    }
    //每个球体颜色不同,所以他们的材质也不同;用函数设置材质
    void setMartiral(const GLfloat mat_diffuse[4], GLfloat mat_shininess)
    {
    	static const GLfloat mat_specular[] = { 0.0f,0.0f,0.0f,1.0f };
    	static const GLfloat mat_emission[] = { 0.0f,0.0f,0.0f,1.0f };
    
    	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_diffuse);
    	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    	glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
    	glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess);
    }
    
    void myDisplay(void)
    {
    	//定义三个球的材质颜色
    	const static GLfloat red_color[] = { 1.0f,0.0f,0.0f,1.0f };
    	const static GLfloat green_color[] = { 0.0f,1.0f,0.0f,0.333f };
    	const static GLfloat blue_color[] = { 0.0f,0.0f,1.0f,0.5f };
    
    	//清除屏幕
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	//启动混合并设置混合因子
    	glEnable(GL_BLEND);
    	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA);
    
    	//设置光源
    	setLight();
    
    	//以(0,0,0.5)为中心,绘制一个半径为3的不透明红色球体(里离观察者最远)
    	setMartiral(red_color, 30.0);
    	glPushMatrix();
    	glTranslatef(0.0f, 0.0f, 0.5f);
    	glutSolidSphere(0.3, 30, 30);
    	glPopMatrix();
    
    	//下面绘制半透明物体,因此将深度缓冲设置为只读
    	glDepthMask(GL_FALSE);
    
    	//以(0.2,0,-0.5)为中心,绘制一个半径为2 的半透明蓝色球体(离观察者近)
    	setMartiral(blue_color, 30.0);
    	glPushMatrix();
    	glTranslated(0.2f, 0.0f, -0.5f);
    	glutSolidSphere(0.2, 30, 30);
    	glPopMatrix();
    
    	//完成半透明物体的绘制,将深度缓冲区会服务可读可写的形式
    	glDepthMask(GL_TRUE);
    
    	glutSwapBuffers();
    	glFlush();/*,保证前面的 OpenGL 命令立即执行(而不是让它们在缓冲区中等待)。其作用跟 fflush(stdout)类似。 */
    }
    
    void myIdle(void)
    {
    	++angle;
    	if (angle >= 360.0f)
    		angle = 0.0f;
    	myDisplay();
    }
    
    int main(int argc, char *argv[])
    {
    	glutInit(&argc, argv);		/*glutInit,对 GLUT 进行初始化,这个函数必须在其它的 GLUT 使用之前调用一次。 */
    	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);	/*设置显示方式,GLUT_RGB 表示使用 RGB 颜色,
    													 与之对应的还有 GLUT_INDEX(表示 使用索引颜色)。
    													 GLUT_SINGLE 表示使用单缓冲,
    													 与之对应的还有 GLUT_DOUBLE(使用双缓冲)。*/
    	glutInitWindowPosition(100, 100);	/*设置窗口在屏幕中的位置*/
    	glutInitWindowSize(400, 400);		/*设置窗口的大小*/
    	glutCreateWindow("混合");			/*根据前面设置的信息创建窗口。参数将被作为窗口的标题。
    					注意:窗口被创建后,并不立即显示到屏幕上。需要调用 glutMainLoop 才能看到窗口。*/
    	glutDisplayFunc(&myDisplay);
    	glutIdleFunc(&myIdle);
    	glutMainLoop();		 /*进行一个消息循环*/
    	return 0;
    }
    
    展开全文
  • opengl编程学习笔记()(2D绘图)

    万次阅读 2009-04-07 10:32:00
    在opengl中可以绘制二维图像,分为两种,BITMAP和image1.bitmap和image的区别有:bitmap中对图像的每个像素只存储一位(0或1),用来表示用当前颜色绘制还是不绘制,而image图像的每个像素存储可能很多位,存储它...
  • Mat和Matlab里的数组格式有点像,但一般是二维向量,如果是灰度图,一般存放类型;如果是RGB彩色图,存放类型。 单通道灰度图数据存放格式: 多通道的图像中,每列并列存放通道数量的子列,如RGB通道彩色图...
  • Mat和Matlab里的数组格式有点像,但一般是二维向量,如果是灰度图,一般存放类型;如果是RGB彩色图,存放类型。 单通道灰度图数据存放格式: 多通道的图像中,每列并列存放通道数量的子列,如RGB通道...
  • 一张图片用三维数组表示 3001003 三个色彩通道 RGB计算机 看来矩阵的形式,图像由像素点组成的,数组中每个元素都是像素点,每个像素点的取值范围【0,255】,像素点越大,亮度越高 做深度学习的任务步骤,跟机器...
  • UI设计师ps的使用,产品经理

    千次阅读 2020-06-07 08:55:23
    看作品到底是二维还是三维的看制作这个作品的工具,新建文档的时候,坐标是二维的,还是三维的 平面的、二维的:Adobe Photoshop、Illustrator、Flash,CorelDraw 立体的、三维的:Autodesk Maya、AutoCAD、3DMAX ...
  • 基于GLT法的风云号气象卫星校正

    千次阅读 2014-12-08 23:12:05
    地理位置查找表文件一个二维图像文件,文件中所包含两个波段:地理校正图像的行和列,文件对应的灰度值表示原始图像每个像素对应的地理位置坐标信息,用有符号整型储存,它的符号说明输出像元对应于真实的输入像...
  • 激光雷达点云数据内部空点补全

    千次阅读 2018-03-29 17:24:47
    点云数据区别于图像数据,不管是二维图像还是三维图像,图像数据都充满整个区域,二维图像中每个像素点都有值,灰度值、RGB值等;三维图像中有体数据(Voxel),根据光线投影算法等,可计算出每个体数据对应值,从而...
  • 我们可以在尺度空间和二维平面中检测到局部最大值,如(x,y,sigma),这表示sigma尺度中(x,y)点可能一个关键点。但是这个LoG的计算量非常大,所以SIFT算法使用高斯差分算子(DoG)来对LoG做近似。 DoG下图这...
  • 002-keras简单应用

    2018-11-05 07:39:00
    # Keras为图片数据输入提供了一个很好的接口,即Keras.preprocessing.image.ImageDataGenerator类# 这个类生成一...多维矩阵的不同维度对应的信息# 分别图像二维像素点,第三维对应于色彩通道,因此如果灰度图...
  • Live2D.rar

    2019-05-21 08:43:58
    live2d由日本Cybernoids公司开发,通过扭曲像素位置营造伪3d空间感的二维动画软件。官网下载安装包直接安装可以得到两种软件,分别Cubism Modeler和Cubism Animator,最后我们还需要安装第个软件Viewer用作...
  • 基于SIFT+python光流算法的速度识别与位移检测首先 还是先科普一下SIFT吧 ...这些,统统不重要,他们不过是三维/二维矩阵而已。640*480的图像,共有那么多的像素点。每一个点用什么代表?灰度就是0-25
  • 纯干货!live2d动画制作简述以及踩坑

    万次阅读 多人点赞 2018-10-11 17:25:13
    1. 概述live2d由日本Cybernoids公司开发,通过扭曲像素位置营造伪3d空间感的二维动画软件。官网下载安装包直接安装可以得到两种软件,分别Cubism Modeler和Cubism Animator,最后我们还需要安装第个软件Viewer...
  • 圆检测技术: 圆检测技术目前用处还是...Hough梯度法的第一步就是找到这些圆心,这样三维的累加平面就转化为二维累加平面。第二步就是根据所有候选中心的边缘非零像素对其的支持程度来确定半径。  从平面坐标到极坐
  • 首先还是以前课程的连接: 第一课,编写第一个OpenGL程序 第课,绘制几何图形 第三课,绘制几何图形的一些细节问题 第四课,颜色的选择 第五课,三维的空间变换 第六课,动画的制作 第七课,使用光照来表现立体感 ...
  • 更强更直观的感受,从三维转跳转到现在的VR全景可以让人如亲临其境一般感受到周边真实的自然场景,区别于传统的平面图。 .全方位,可以依据自己意愿的去观赏不一样的角度,而且可以与场景中特殊功能进行互动 三....
  • 图像增强的实现

    2012-06-07 15:42:03
    说明:对于 Y=filter2(B,X) ,filter2 使用矩阵 B 中的二维 FIR 滤波器对数据 X 进行滤波,结果 Y 通过二维互相关计算出来的,其大 小与 X 一样;对于 Y=filter2(B,X,'shape') ,filter2 返回的 Y 通过二维互相...

空空如也

空空如也

1 2 3
收藏数 43
精华内容 17
关键字:

像素是二维还是三维