编程+游戏:将Kinect与Processing结合进行编程
二锅头【Processing+Kinect】教程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
KinectPV2 library for processing 下载地址:GitHub – ThomasLengeling/KinectPV2: Kinect4W 2.0 library for Processing
演示视频:
二锅头【Processing+Kinect】教程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
KinectPV2 library for processing 下载地址:GitHub – ThomasLengeling/KinectPV2: Kinect4W 2.0 library for Processing
演示视频:
转载自:Getting Started with Kinect and Processing | Daniel Shiffman
The Microsoft Kinect sensor is a peripheral device (designed for XBox and windows PCs) that functions much like a webcam. However, in addition to providing an RGB image, it also provides a depth map. Meaning for every pixel seen by the sensor, the Kinect measures distance from the sensor. This makes a variety of computer vision problems like background removal, blob detection, and more easy and fun!
The Kinect sensor itself only measures color and depth. However, once that information is on your computer, lots more can be done like “skeleton” tracking (i.e. detecting a model of a person and tracking his/her movements). To do skeleton tracking you’ll need to use Thomas Lengling’s windows-only Kinect v2 processing libray. However, if you’re on a Mac and all you want is raw data from the Kinect, you are in luck! This library uses libfreenect and libfreenect2 open source drivers to access that data for Mac OS X (windows support coming soon).
领先的沉浸式互联网内容门户,一站式学习、创作和展示。沉浸式互联网体验和学习门户 – 踏得网 (techbrood.com)
可以在线编辑场景,实时渲染,非常流畅好用。这个特别适合制作虚拟仿真实验。
带有网页版3D编辑器,非常流畅。Stone – 网页3D在线编辑器,快速构建和分享沉浸式展示 1.0.1 (techbrood.com)
案例欣赏:
动态草地:
水池:
这是在Processing官网上找到的一个例子:A Processing implementation of Game of Life
程序源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
// Size of cells int cellSize = 5; // How likely for a cell to be alive at start (in percentage) float probabilityOfAliveAtStart = 15; // Variables for timer int interval = 100; int lastRecordedTime = 0; // Colors for active/inactive cells color alive = color(0, 200, 0); color dead = color(0); // Array of cells int[][] cells; // Buffer to record the state of the cells and use this while changing the others in the interations int[][] cellsBuffer; // Pause boolean pause = false; void setup() { size (640, 360); // Instantiate arrays cells = new int[width/cellSize][height/cellSize]; cellsBuffer = new int[width/cellSize][height/cellSize]; // This stroke will draw the background grid stroke(48); noSmooth(); // Initialization of cells for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { float state = random (100); if (state > probabilityOfAliveAtStart) { state = 0; } else { state = 1; } cells[x][y] = int(state); // Save state of each cell } } background(0); // Fill in black in case cells don't cover all the windows } void draw() { //Draw grid for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { if (cells[x][y]==1) { fill(alive); // If alive } else { fill(dead); // If dead } rect (x*cellSize, y*cellSize, cellSize, cellSize); } } // Iterate if timer ticks if (millis()-lastRecordedTime>interval) { if (!pause) { iteration(); lastRecordedTime = millis(); } } // Create new cells manually on pause if (pause && mousePressed) { // Map and avoid out of bound errors int xCellOver = int(map(mouseX, 0, width, 0, width/cellSize)); xCellOver = constrain(xCellOver, 0, width/cellSize-1); int yCellOver = int(map(mouseY, 0, height, 0, height/cellSize)); yCellOver = constrain(yCellOver, 0, height/cellSize-1); // Check against cells in buffer if (cellsBuffer[xCellOver][yCellOver]==1) { // Cell is alive cells[xCellOver][yCellOver]=0; // Kill fill(dead); // Fill with kill color } else { // Cell is dead cells[xCellOver][yCellOver]=1; // Make alive fill(alive); // Fill alive color } } else if (pause && !mousePressed) { // And then save to buffer once mouse goes up // Save cells to buffer (so we opeate with one array keeping the other intact) for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { cellsBuffer[x][y] = cells[x][y]; } } } } void iteration() { // When the clock ticks // Save cells to buffer (so we opeate with one array keeping the other intact) for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { cellsBuffer[x][y] = cells[x][y]; } } // Visit each cell: for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { // And visit all the neighbours of each cell int neighbours = 0; // We'll count the neighbours for (int xx=x-1; xx<=x+1;xx++) { for (int yy=y-1; yy<=y+1;yy++) { if (((xx>=0)&&(xx<width/cellSize))&&((yy>=0)&&(yy<height/cellSize))) { // Make sure you are not out of bounds if (!((xx==x)&&(yy==y))) { // Make sure to to check against self if (cellsBuffer[xx][yy]==1){ neighbours ++; // Check alive neighbours and count them } } // End of if } // End of if } // End of yy loop } //End of xx loop // We've checked the neigbours: apply rules! if (cellsBuffer[x][y]==1) { // The cell is alive: kill it if necessary if (neighbours < 2 || neighbours > 3) { cells[x][y] = 0; // Die unless it has 2 or 3 neighbours } } else { // The cell is dead: make it live if necessary if (neighbours == 3 ) { cells[x][y] = 1; // Only if it has 3 neighbours } } // End of if } // End of y loop } // End of x loop } // End of function void keyPressed() { if (key=='r' || key == 'R') { // Restart: reinitialization of cells for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { float state = random (100); if (state > probabilityOfAliveAtStart) { state = 0; } else { state = 1; } cells[x][y] = int(state); // Save state of each cell } } } if (key==' ') { // On/off of pause pause = !pause; } if (key=='c' || key == 'C') { // Clear all for (int x=0; x<width/cellSize; x++) { for (int y=0; y<height/cellSize; y++) { cells[x][y] = 0; // Save all to zero } } } } |
使用说明:
按空格键暂停,并可以用鼠标点击格子来激活/取消激活某个格点,再按空格继续。
按R键重置并随机生成一些格点。
按C清空所有格点。
请查看全文看在线展示。
阅读全文
对于 Genuino 101(在美国叫做 Arduino 101),目前最新的 Arduino IDE 还默认不会支持,需要手动安装驱动。
将 Genuino 101 插入电脑 USB ,等待基本驱动安装完毕后,打开 Arduino IDE。
然后打开“开发板管理器”,在“开发板管理器”中找到“Intel Curie Bords by Intel”,在右边点安装。
等4个步骤全部下载安装完毕后,将 Arduino IDE 关闭,拔出 Genuino 101。
重新打开 Arduino IDE ,插入 Genuino 101。在开发板选择中选中 Genuino 101。端口应该会自动识别,如果没有正确识别,再勾选正确的端口。
本段参考Arduino.cc官网指南:https://www.arduino.cc/en/Tutorial/Genuino101CurieIMUOrientationVisualiser
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
#include <CurieIMU.h> #include <MadgwickAHRS.h> Madgwick filter; unsigned long microsPerReading, microsPrevious; float accelScale, gyroScale; void setup() { Serial.begin(9600); // start the IMU and filter CurieIMU.begin(); CurieIMU.setGyroRate(25); CurieIMU.setAccelerometerRate(25); filter.begin(25); // Set the accelerometer range to 2G CurieIMU.setAccelerometerRange(2); // Set the gyroscope range to 250 degrees/second CurieIMU.setGyroRange(250); // initialize variables to pace updates to correct rate microsPerReading = 1000000 / 25; microsPrevious = micros(); } void loop() { int aix, aiy, aiz; int gix, giy, giz; float ax, ay, az; float gx, gy, gz; float roll, pitch, heading; unsigned long microsNow; // check if it's time to read data and update the filter microsNow = micros(); if (microsNow - microsPrevious >= microsPerReading) { // read raw data from CurieIMU CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz); // convert from raw data to gravity and degrees/second units ax = convertRawAcceleration(aix); ay = convertRawAcceleration(aiy); az = convertRawAcceleration(aiz); gx = convertRawGyro(gix); gy = convertRawGyro(giy); gz = convertRawGyro(giz); // update the filter, which computes orientation filter.updateIMU(gx, gy, gz, ax, ay, az); // print the heading, pitch and roll roll = filter.getRoll(); pitch = filter.getPitch(); heading = filter.getYaw(); Serial.print("Orientation: "); Serial.print(heading); Serial.print(" "); Serial.print(pitch); Serial.print(" "); Serial.println(roll); // increment previous time, so we keep proper pace microsPrevious = microsPrevious + microsPerReading; } } float convertRawAcceleration(int aRaw) { // since we are using 2G range // -2g maps to a raw value of -32768 // +2g maps to a raw value of 32767 float a = (aRaw * 2.0) / 32768.0; return a; } float convertRawGyro(int gRaw) { // since we are using 250 degrees/seconds range // -250 maps to a raw value of -32768 // +250 maps to a raw value of 32767 float g = (gRaw * 250.0) / 32768.0; return g; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
import processing.serial.*; Serial myPort; float yaw = 0.0; float pitch = 0.0; float roll = 0.0; void setup() { size(600, 500, P3D); // if you have only ONE serial port active myPort = new Serial(this, Serial.list()[0], 9600); // if you have only ONE serial port active //必须注意,如果你运行无效,但是知道自己用的哪个COM口,就修改一下这里的代码。 // if you know the serial port name //myPort = new Serial(this, "COM5", 9600); // Windows,注意官网上有错误,COM5后应该没有冒号:才对 //myPort = new Serial(this, "/dev/ttyACM0", 9600); // Linux //myPort = new Serial(this, "/dev/cu.usbmodem1217321", 9600); // Mac textSize(16); // set text size textMode(SHAPE); // set text mode to shape } void draw() { serialEvent(); // read and parse incoming serial message background(255); // set background to white lights(); translate(width/2, height/2); // set position to centre pushMatrix(); // begin object float c1 = cos(radians(roll)); float s1 = sin(radians(roll)); float c2 = cos(radians(pitch)); float s2 = sin(radians(pitch)); float c3 = cos(radians(yaw)); float s3 = sin(radians(yaw)); applyMatrix( c2*c3, s1*s3+c1*c3*s2, c3*s1*s2-c1*s3, 0, -s2, c1*c2, c2*s1, 0, c2*s3, c1*s2*s3-c3*s1, c1*c3+s1*s2*s3, 0, 0, 0, 0, 1); drawArduino(); popMatrix(); // end of object // Print values to console print(roll); print("\t"); print(pitch); print("\t"); print(yaw); println(); } void serialEvent() { int newLine = 13; // new line character in ASCII String message; do { message = myPort.readStringUntil(newLine); // read from port until new line if (message != null) { String[] list = split(trim(message), " "); if (list.length >= 4 && list[0].equals("Orientation:")) { yaw = float(list[1]); // convert to float yaw pitch = float(list[2]); // convert to float pitch roll = float(list[3]); // convert to float roll } } } while (message != null); } void drawArduino() { /* function contains shape(s) that are rotated with the IMU */ stroke(0, 90, 90); // set outline colour to darker teal fill(0, 130, 130); // set fill colour to lighter teal box(300, 10, 200); // draw Arduino board base shape stroke(0); // set outline colour to black fill(80); // set fill colour to dark grey translate(60, -10, 90); // set position to edge of Arduino box box(170, 20, 10); // draw pin header as box translate(-20, 0, -180); // set position to other edge of Arduino box box(210, 20, 10); // draw other pin header as box } |
运行视频:
https://www.taho.space/wp-content/uploads/genuino101test.wmv
知乎上有个问题:物理专业自学计算机应该学些什么?
题目大概是说他物理本科大四了,申请去美国读物理博士,但自己对计算机有很大兴趣,为了考虑以后的饭碗,想自学计算机。自己对计算机图形学有兴趣,希望得到一些建议。
回答的人不少,有几个人的回答震撼到我了。
个人站的角度不同,现在的答案基本都是从图形学的角度建议,我换个角度。
从研究生计算机科学做研究的角度来讲,我认为本科最适合的专业首先是物理,其次是数学,再次才是计算机。数学学的太抽象,抽象层次太高,研究现实问题的人往往处在鄙视链的底端。计算机学的太底层,对于概率论、随机过程、线性代数等学科学的太少,不了解建模分析的那套方法论。而物理学一方面的数学知识足够多,另外一方面主要研究的方法也是对这个世界建模,然后进行观测,这与前沿的机器学习领域做的事情几乎是一样的。至于会不会写代码,其实科研里面要写的代码不多,主要都是在推公式,研究如何设计模型使得其拥有很多良好的性质。代码很多时候写写matlab就可以了。
所以恭喜你,如果你想转行做CS的科研,你有很大的优势。事实上,很多CS领域的大神都是学物理的,比如华人图灵奖得主姚期智,CMU Machine Learning领域大神Alex Smola。
如果你真的励志做CS相关的研究的话,物理PhD的选择最好到CS极好的学校,比如UCB, CMU, MIT, Stanford,一般这些学校都可以辅修Machine Learning的Master, 多修CS相关的课程,都是很好的选择。Coursera上的Machine Learning课程都很入门,如果想进阶,你可以看看CMU 10701(Machine Learning), 10702(Statistical Machine Learning), 10708(Probabilitic Graphic Model) 课程的课件、视频、相关阅读和作业,基本都不需要写代码,主要是数学证明、建模和分析。
当然,如果你想做应用而不是做理论什么的,当我以上没说。
作者:Milo Yip
链接:https://www.zhihu.com/question/23212279/answer/23940891
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
其实在计算机图形学里有很多与物理相关的课题,例如物理模拟(刚体、柔体、流体等)、基于物理的渲染(光源、材质、媒介等),还有一些涉及物理的跨学科课题,例如生物力学、基于物理的声音渲染、光场摄影等等。简单介绍几本书
有空可以看看最前沿的图形学发展,特别是当中涉及物理部分的
看看那些文献的作者网站,可能会发现不少研究者都有物理背景。
我觉得能做理论物理研究的人,其智商做哪种科学问题也不大吧。而计算机科学之本就是算法,无论是哪一个应用方向都是必须的,建议深入学习。个人不建议浪费时间在API、OS、UI编程上面,不竟这些东西许多人都能做,有研究能力的人可以探索新世界。因为游戏、动画、电影这些娱乐工业,计算机图形学的职位在行业上也有需求。
移动开发:学习学习swift吧。玩玩iOS。。总是觉得Android怪怪的
学习轨迹:
1.熟练使用linux/unix(格式化硬盘一个月内可以生存)
2.选一个自己顺手的IDE(vim/emacs/VS),基本熟练cpp、python(均指一万行代码,可以写写计算物理习题)
3.搭建一个自己的服务器(using http://aws.amazon.com ec2)
4.写一个桌面app .net/cocoa,(学c#/o-c),在这里折腾OpenGL CUDA等
5.写一个绚烂的个人网站use Django&html5&css3&webgl
6.研究妹子回你短信速度和她对你好感度的关系(使用支持向量机/deep learning)
7.学习CUDA并在你的pc上模拟EAST using MHD model in FEA
(其实能跑出来一个N-S方程出来个卡门涡街就很好了)
8.学习单片机并且控制一架四轴飞行器给那个追了四年没追的女神泼一盆冷水(someone你丫两年以后给我等着)。
可以适当从ROS+树莓派入手,加上一些有意思的硬件比如kinect什么的,就很好玩,推荐学习OpenCV(人脸识别)+讯飞各种接口(语音)。
对了。。。工程控制论,或者什么ML,DataMining的数学比物理口的数学真的是弱爆了。一群不用解偏微分方程的渣渣。
顺便抛我的blog http://stlover.org(呃最近好像数据库挂了)
就这些差不多了…剩下做点小项目自己也就会了
=====================
操作系统建议看看,就是看看而已。。我大二选了操作系统课最后发现完全没听。
编译原理没有必要,想深入学推荐MIT的计算机结构和解释同时学习LISP
第一个回答站在常春藤留学生的视角给出了实用的建议。给我的感觉就是,国外的课程比国内大学的课程领先了太多了,似乎这些课程已经完全成熟和系统化了,而国内还比较杂,很多人还必须去看网络课程来学习。这从一个侧面能看出,国内学生相比国外学生这方面受教育的深度和看问题的视野是有差距的,而且这样网络封闭的话,很不好弥补。
第二个回答罗列了不少书籍,都是物理和游戏、计算等相关的计算机书籍。这类书籍国内也越来越多,不过不得不说的是,大多好的教材,似乎都是外国人写的,中国引入翻译版(书的好坏甚至还要取决于译者的水准)。也就是说,好的教材都是英文的,大家最好学好英文,方便自己掌握知识。这也提醒我们,我们与他们的差距还是很大的。
第三个回答深深震撼到我了。一个大二学生,已经对计算机技术掌握了这么多,真是不简单啊。我感觉他做的事情如果让我去做,没有几年是做不完的。其中他讲到了Python、C#编程,js编程、html、css、javascript(也许他还会java呢),swift,用到了U3D,还会使用SUDA,也玩开源硬件,arm编程,而且非常擅长Python(用Python结合其他框架做了网站,做了GUI编程等)。学习MachineLearning(机器学习)、DataMining(数据挖掘),还会OpenCV、讯飞API。这个答案是答主在2年前回答的,估计现在已经用到了Google、百度的接口(语音接口还是很强大的),做模式识别,可能还有很多我根本没有听过的,也不知道存在的技术。我非常佩服他,
第四个回答比较理性。他简单澄清了物理和计算机的关系,并建议去做最基本的事情。题主感谢了他,而且题主已经走上了计算物理的道路。“我现在业余时间主要关心机器学习方面的东西,因为背后的数学支持挺对我胃口。我自己的科研方向也正是量子计算,我还在尝试涉猎量子计算+机器学习的交叉。”题主这样回答。
我摘下眼镜,停下来想了想。
普通大众忙忙碌碌,做的事情对他们来说可能过于简单了。世界上就是有这么一小部分人,走在人类发展的前列。虽然和大家一样一日三餐,闲了也玩耍逗乐,但静下来的时候,很多人选择看电视打牌睡觉娱乐,而他们选择去钻研他们的兴趣。
上面的只是物理和计算机的话题。其实,无论是摄影,研究昆虫,或者是别的什么,只要是钻进兴趣里了,人生不会太枯燥,追求也就不会太乏味。我不想说谁的生活更有意义,至少,这么些人的其中一些人做的事,会影响很多人。我感觉,他们活着的意义更大一些吧。
在广场的大屏幕上看到了随韵律跳动的闪烁图谱,就想知道用Processing该怎样编出来这样的效果呢?于是就出现了下面的拙劣产品。
优点:有点效果了;
缺点:不能随韵律跳动,也没有节奏,需要改进。
源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void setup() { size(600, 600); smooth(); background(0); colorMode(RGB,255); noFill(); } void draw() { for(int d=0;d<80;d+=10) { for(int x=50;x<640;x+=100) { for(int y=50;y<640;y+=100) { stroke(random(255),random(255),random(255)); strokeWeight(4); rectMode(CENTER); //fill(random(255),random(255),random(255),50); rect(x,y,d,d); } } } } |
效果:
代码:(代码转载自:http://ubaa.net/shared/processing/opencv/blob.html)
[cc lang=”c”]
import hypermedia.video.*;
OpenCV opencv;
void setup() {
size( 640, 480 );
// open video stream
opencv = new OpenCV( this );
opencv.capture( 640, 480 );
}
void draw() {
background(192);
opencv.read(); // grab frame from camera
opencv.threshold(80); // set black & white threshold
// find blobs
Blob[] blobs = opencv.blobs( 10, width*height/2, 100, true, OpenCV.MAX_VERTICES*4 );
// draw blob results
for( int i=0; i
1.Processing 的祖父 John Maeda 在TED的演讲
他工作于设计、科技、领导力以及它们交叉汇合的领域。 他曾经任教于著名的 MIT Media Lab Aesthetics and Computation Group(媒体实验室美学与计算小组) 正是在那期间,他所带的学生 Casey Reas 及 Ben Fry 发明了 Processing。 由这两位作者撰写的蓝色封面的 Processing Handbook 一书便是由他作序。 作为 Processing 的前身,教学用编程语言Design By Numbers(DBN)也是由他开发。 不论是 Processing 还是 Design By Numbers,他们都有着相同的初衷——让更多的非程序员快乐地学会编程。 现在他的身份是 Rhode Island School of Design / 罗德岛设计学院 的校长。 他的推特帐号为 @johnmaeda 他有一本影响深远的著作《简单法则》(The law of simplicity)。
2. Hello World! Processing(关于编程语言Processing的纪录片)
内容来自于:http://arduino.cc/en/Reference/Comparison
The Arduino language (based on Wiring) is implemented in C/C++, and therefore has some differences from the Processing language, which is based on Java.
Arduino 语言遵循C/C++标准,而 Processing 语言遵循的是Java标准,因此会有一些不同。
Arduino | Processing |
int bar[8]; bar[0] = 1; |
int[] bar = new int[8]; bar[0] = 1; |
int foo[] = { 0, 1, 2 }; | int foo[] = { 0, 1, 2 }; or int[] foo = { 0, 1, 2 }; |
Arduino | Processing |
int i; for (i = 0; i < 5; i++) { … } |
for (int i = 0; i < 5; i++) { … } |
Arduino | Processing |
Serial.println(“hello world”); | println(“hello world”); |
int i = 5; Serial.println(i); |
int i = 5; println(i); |
int i = 5; Serial.print(“i = “); Serial.print(i); Serial.println(); |
int i = 5; println(“i = ” + i); |
Corrections, suggestions, and new documentation should be posted to the Forum.
The text of the Arduino reference is licensed under a Creative Commons Attribution-ShareAlike 3.0 License. Code samples in the reference are released into the public domain.
(自2008 至 2021的所有文章,除标明“转载”外)版权©归 TAHO 所有 | 转载请务必注明出处 | 联系TAHO