matlab 中文乱码

如果是matlab本身显示中文乱码:
在控制面板->修改时间和数字格式->简体中文,重启matlab即可。

如果是matlab读取txt文件乱码:
则    [fid, msg] = fopen(fname, 'r', 'n', 'UTF-8');
        string = fscanf(fid, '%s');
此处fopen的编码格式要和实际的txt一致,保存的什么格式,就要指明用什么格式打开,就不会出错了。

无线电自学书籍

1. 《从零起步学电子》;
2. 《无线电基础电路实作》;
3. 《业余无线电射频干扰解决全方案》;
4. (如果需要在低功率/QRP下工作)《小功率的力量:QRP制作》;
5. 《天线手册》。
外加 <<业余无线电手册>>

xvfb ffmpeg wmctrl 配置

做虚拟屏幕,为了把服务器上几个app映射到一个画面上,再把这个画面通过wifi显示到远程物理屏幕,特此研究了xvfb ffmpeg wmctrl 的配置。

1. Xvfb
xvfb 是 x 服务虚拟缓存,简单的说,就是把本该输出到物理屏幕的图像,输出到缓存里。这个缓存就是内存,并且自动映射到文件系统(一个文件)。具体参数:http://www.xfree86.org/4.0/Xvfb.1.html

做一个简单的测试,在ubuntu服务器上,新建两个虚拟屏幕:

sudo apt-get install xvfb firefox x11-apps imagemagick 
这里 firefox x11-apps和 imagemagick只是用来方便测试。

Xvfb :1 -screen 0 600x840x16 -screen 1 1024x768x16 -fbdir /home/fu/ar/xvfb &

Display=:1.0 import -window root 0.png
(如图,因为暂时没有程序投影到这个桌面,所以是空桌面,600x800的全黑图);

Display=:1.1 import -window root 1.png
(同理,得到一个1024x768的全黑图)

现在制定虚拟屏幕运行firefox,因为只有x服务,并没有windows manager,所以理论上,一个x程序(所谓x程序,就是有界面的程序)应该非常原始的出现在指定屏幕的左上角。

Display=:1.0 firefox http://www.google.com &


Display=:1.1 xcalc &


看来没有窗口管理器是不行的,之后还要涉及到窗口的focus什么的,还是得装一个窗口管理器。这里选择openbox,因为强大的可配置性,以及极少的空间占用。

sudo apt-get install openbox

Xvfb :1 -screen 0 600x840x24 -screen 1 1024x768x24 -fbdir /home/fu/ar/xvfb &
sleep 3;
DISPLAY=:1.0 openbox &
DISPLAY=:1.1 openbox &
#DISPLAY=:1.0 fluxbox &
#DISPLAY=:1.1 fluxbox &

这里屏幕用24位彩色,是为了RGB都是3字节,和通用的图形软件,opencv,matlab什么的都对应起来。

import 无法截openbox的屏,只有窗口框,里面是黑的。截fluxbox的屏幕没有任何问题。替代方法是用scrot来截屏,或者其他什么软件,就是不要用 import。

sudo apt-get install scrot

用ps kill 掉之前的程序,重新运行一遍:
DISPLAY=:1.0 xcalc &
DISPLAY=:1.1 xclock -digital -update 1 &
DISPLAY=:1.0 scrot 0.png


DISPLAY=:1.1 scrot 1.png



这下子可以顺利看到xvfb+openbox的实际情况了。可以看到,openbox默认是居中对齐。

也可以通过opencv,在程序里捕捉和显示各个桌面:

//testXwd.cpp 
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include "iostream"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cstring>
#include <vector>

using namespace std;
using namespace cv;

IplImage *XImage2IplImageAdapter(XImage *ximage){
        IplImage *iplImage;
        assert(ximage->format == ZPixmap);
        assert(ximage->depth == 24);

        iplImage = cvCreateImageHeader(
                cvSize(ximage->width, ximage->height),
                IPL_DEPTH_8U,
                ximage->bits_per_pixel/8);

        iplImage->widthStep = ximage->bytes_per_line;
        if(ximage->data != NULL)
                iplImage->imageData = ximage->data;

        return iplImage;
}

int main(int argc, char* argv[]){
    int Width = 0;
    int Height = 0;
    int Bpp = 0;
    std::vector<unsigned char> Pixels;

    namedWindow("MyVideo",CV_WINDOW_AUTOSIZE);
    Mat frame;
    Display* display = XOpenDisplay(argv[1]);
    Window root = DefaultRootWindow(display);

    while(1){
    XWindowAttributes attributes = {0};
        XGetWindowAttributes(display, root, &attributes);

        XImage* img = XGetImage(display, root, 0, 0 , attributes.width, attributes.height, AllPlanes, ZPixmap);
    IplImage *cvImageSample = XImage2IplImageAdapter(img);
    frame = Mat(cvImageSample);
        imshow("MyVideo", frame);
        if(waitKey(50) == 27) {
            cout << "esc key is pressed by user" << endl;
        break;
    }
    XDestroyImage(img);
    }
    XCloseDisplay(display);
    return 0;
}
//makefile
testXwd: testXwd.cpp
    g++ -g testXwd.cpp -I/usr/local/include/ -L/usr/local/lib -lopencv_highgui -lopencv_core -lopencv_imgproc -fopenmp -o testXwd

//example
testXwd :1.1

2. Ffmpeg 

为了能够实时的观看某个程序,可以用ffmpeg x11grab来捕捉其所在的屏幕。因为我把每个程序放在单独的屏幕,所以捕捉屏幕等同于捕捉程序窗口。

ffmpeg -y -r 15 -f x11grab -s 1024x768 -i :1.1 out.avi

ffmpeg 会自动选择编码,打开录制的out.avi,窗口大小是对的,电子表也在走。

再测试通过网络发送到opencv:

ffmpeg  -r 15 -f x11grab -s 1024x768 -i :0.0 -vcodec mpeg4 -qscale 12 -f mpegts udp://127.0.0.1:6666?pkt_size=188?buffer_size=65535

ffmpeg -r 20 -f x11grab -s 1024x768 -i :0.0 -vcodec mpeg4 -maxrate 900k -bufsize 900k -qscale 10 -f mpegts udp://127.0.0.1:6666



//testRtp.cpp
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include "iostream"

using namespace std;
using namespace cv;

int main(int argc, char* argv[]){
    VideoCapture cap("udp://127.0.0.1:6666");
    if ( !cap.isOpened() ) {
         cout << "Cannot open the video file" << endl;
         return -1;
    }
    double fps = cap.get(CV_CAP_PROP_FPS);
    cout << "Frame per seconds : " << fps << endl;
    namedWindow("MyVideo",CV_WINDOW_AUTOSIZE);
    Mat frame;
    while(1){
        bool bSuccess = cap.read(frame);
    if (!bSuccess){
        cout << "Cannot read the frame from video file" << endl;
        break;
    }
        imshow("MyVideo", frame);
        if(waitKey(30) == 27) {
            cout << "esc key is pressed by user" << endl;
        break;
    }
    }
    return 0;
}

//makefile
testRtp: testRtp.cpp
    g++ -g testRtp.cpp -I/usr/local/include/ -L/usr/local/lib -lopencv_highgui -lopencv_core -lopencv_imgproc -fopenmp -o testRtp

尽管只消耗500kbps的带宽,效果却非常不理想。



Matlab读取摄像头

% cam_info = imaqhwinfo('winvideo');
% cam_info.DeviceInfo.DeviceID
% cam_info.DeviceInfo.SupportedFormats

close all;
if(exist('vid','var'))
    stop(vid);
    delete(vid);
end

%imaqhwinfo

vid = videoinput('winvideo', 1, 'YUY2_1280x720');
set(vid, 'ReturnedColorSpace', 'RGB');
% preview(vid);

src = getselectedsource(vid);
frameRates = set(src, 'FrameRate');
src.FrameRate = frameRates{1};
actualRate = str2num( frameRates{1} )

avi = avifile('timelapsevideo','fps',actualRate);

triggerconfig(vid, 'manual');
start(vid);

for i=1:100
    img=getsnapshot(vid);
%     imshow(img);
%     pause(0.01);
    F = im2frame(img);      % Convert I to a movie frame
    avi = addframe(avi,F);  % Add the frame to the AVI file
end;

stop(vid)
delete(vid);

avi = close(avi);      

凸边形检测

检测凸性的方法是检测多边形上是否有凹点,如果一个都没有找到,就是凸多边形。它的基本想法是每个顶点的转向应该一致,任何转向不一致的点都是凹点。

怎样检测一个点的转向呢?技巧是利用边向量的叉乘,左手坐标系中,如果向量的转向是顺指针,它们的叉乘就会指向你。什么是指向你呢?我们从多边形的正面看,正面由法向量指明。如果没有提供法向量,就必须做一些计算来得到。一旦有了法向量,检查多边形的每个顶点。用相邻的两个边向量计算该顶点的法向量,接着用多边形的法向量和顶点的法向量点乘,检测它们的方向是否相反。如果是(点乘为负),那么这个顶点就是一个凹点。


function isConvex = checkConvex(pts)
% Given a set of points determine if they form a convex polygon
% Inputs 
%  px, py: x and y coordinates of the vertices for a given polygon

% Output 
%  isConvex: 1 or 0 for polygon being convex or concave

    py = pts(:,1);
    px = pts(:,2);

    numPoints = size(px,1);
    if numPoints < 4
        isConvex = 1;
        return
    end

    % can determine if the polygon is convex based on the direction the angles
    % turn.  If all angles are the same direction, it is convex.
    v1 = [px(1) - px(end), py(1) - py(end)];
    v2 = [px(2) - px(1), py(2) - py(1)];
    signPoly = sign(det([v1; v2]));

    % check subsequent vertices
    for k = 2:numPoints-1
        v1 = v2;
        v2 = [px(k+1) - px(k), py(k+1) - py(k)]; 
        curr_signPoly = sign(det([v1; v2]));
        % check that the sign matches the first vectors or is 0
        if curr_signPoly * signPoly < 0
            isConvex = 0;
            return
        end
    end
    % check the last vectors
    v1 = v2;
    v2 = [px(1) - px(end), py(1) - py(end)];
    curr_signPoly = sign(det([v1; v2]));
    if curr_signPoly * signPoly < 0
        isConvex = 0;
    else
        isConvex = 1;
    end
end

wifibot 系统更新

实验室的wifibot,由于预装的是裁剪版的ubuntu10.04,连个NetworkManager都没有,wifibot也不wifi了。经过各种尝试,最终安装上ubuntu14.04 LST。

失败1 尝试配置NetworkManager
本来是想直接在/etc/network/interfaces里配置网络的,可是那个得NetworkManager启动才有用。我又在/etc/rc.local里写入启动NetworkManager的语句,可是并没有自动启动。Linux配置文件复杂之极,未遂。

失败2 尝试wifibot官方镜像
于是又去官网下在了ubuntu12.04的tib镜像,又下载了破解办的acronis制作了usb启动盘。怎奈那个wifibot都不好设置bios启动顺序,只好把sata接口先拔了,这才识别出usb启动。也许是两个usb接口只有一个可以做启动盘接口?因为后来一直从usb启动的,也不用拔sata了。可惜acronis又不争气,总是卡在最后一步就是不安装。作罢。

失败3 尝试windows xp embedded
其实蛮好用的,就是重启后,ad-hoc不自动连接。另外有些服务官方也没说,有空仔细看看。

失败4 尝试ubuntu14.10
最后想来,也不要官方提供的那些软件了,干脆直接装个全新ubuntu吧。usbwriter+iso,高效无比。可惜ubuntu14.10软件源都结束了,没有软件源的ubuntu也没啥用。

成功 安装ubuntu14.04 LST
查了资料,14.04支持到2019年,果断装。再来一遍usbwriter+iso,成功。又配置了wifi ad-hoc,重启也能连上,网线也OK的。又参考了http://www.linuxidc.com/Linux/2014-04/100491.htm ,配置了xfce+xrdp远程桌面。再通过apt-get install libopencv-dev 安装了opencv2.4。一气呵成。

总结,wifibot预装的系统太垃圾了,官网支持也差,简直就是业余爱好者。小车硬件做的不错,但是不值那个钱。

一些资源:
windows下c++操控摄像头旋转 http://web.archive.org/web/20101229215224/http://www.quickcamteam.net/documentation/how-to/how-to-control-pan-tilt-zoom-on-logitech-cameras 。源代码

取消xpe的写保护
  1. Open a command-line window (Start -> Run "cmd") and disable the Write Protection with the following command:  fbwfmgr.exe /disable
  2. Completing this command will require a restart.

windows 7 建立虚拟wifi热点 共享上网

建立WIFI热点:
1、请确认您使用的操作系统是微软的Windows 7或者Windows server 2008 R2。
2、以管理员身份运行命令提示符(用快捷键WIN+R调出运行然后输入CMD打开命令提示符的不是管理员权限),右击“命令提示符”,选择以“管理员身份运行”。
3、在命令提示符下输入命令:netsh wlan set hostednetwork mode=allow
4、继续在命令提示符中输入:netsh wlan set hostednetwork ssid=您想要的无线网络的名称 key=您想要设置的密码
这一步是设置无线网络名称和密码,密码必须8位以上
5、接下来打开网络共享中心–更改适配器设置,你会发现多了一个Microsoft Virtual wlan Miniport Adapter,对了,这个就是我们刚才虚拟出来的无线网络适配器。
6、继续在命令提示符中输入:netsh wlan start hostednetwork
这一步是打开刚才虚拟的无线网络,这样其他电脑和无线终端就能发现你刚才虚拟的网络了。
7、打开网络共享中心发现你现在连接了两个网络了,一个是你的有线网络,另外一个就是虚拟网络
8、打开网络共享中心–更改适配器设置,右击你的已连入网络的网卡(本地连接或宽带连接或无线连接),选择属性,点击共享,勾选“允许其他网络用户通过此计算机的Internet连接还连接”选项,在下拉菜单中选择刚才建立的虚拟网络,无线网络连接2,然后确定。
ps:如果此步骤后出现错误提示“ internet连接共享访问被启用时,出现了一个错误(NULL) ”,
解决办法为:window开始按钮—>在 运行 框中输入 “  services.msc ”—>在弹出的服务管理界面中按一下“W”键,快速跳转到windows 系列服务,找到 “windows firewall”—> 右键选择启动 —> 再次设置启用本地网络连接共享即可。
9、到此为止,其他电脑连接上这个虚拟网络后就能共享上网了!
PS:这种方法比点对点网络共享稳定的多,基本和无线路由没什么区别!并且可以已经连接无线网后再使用wifi共享,而点对点则不行,因为无线网卡不能同时链接两个无线网络。
配置成功后,以后每次只要以管理员身份运行cmd,输入:netsh wlan start hostednetwork
为了方便,可在桌面新建一个记事本文件,输入netsh wlan set hostednetwork mode=allow ssid=你设置的wifi名字 key=你设置的密码(8位以上) 点击保存为 建立wifi.bat文件到桌面,在新建一个输入netsh wlan start hostednetwork 保存为 开启wifi.bat文件,以后上网的时候直接按顺序右键管理员身份运行就可以了。

点到两点间连线距离的公式

有三个点(a,b)、(x0,y0)、(xm,ym)。求点(a,b)到(x0,y0)、(xm,ym)连线距离的表达式:

distance=abs((a-x0)*(y0-ym)-(b-y0)*(x0-xm))/sqrt((y0-ym)^2+(x0-xm)^2)

对应的Matlab程序:

function [distance] = getPtsDis(pts,pt1,pt2)
    distance=abs((pts(:,2)-pt1(2))*(pt1(1)-pt2(1))-(pts(:,1)-pt1(1))*(pt1(2)-pt2(2)))/sqrt(sum((pt1-pt2).^2));
end

Matlab 画圆

plot(x,y,'or','MarkerSize',radiu);

Matlab 数字转 bit

>> b = bitget(11,8:-1:1)

b =

  Columns 1 through 8

     0     0     0     0     1     0     1     1


     

Matlab xyz 转 Meshlab ply格式

function [ ] = write3ply( pts3d,r,g,b )
    fileID = fopen('result.ply','w');
    fprintf(fileID,'ply\n');
    fprintf(fileID,'format ascii 1.0\n');
    fprintf(fileID,'element vertex %i\n',size(pts3d,1));
    fprintf(fileID,'property float x\n');
    fprintf(fileID,'property float y\n');
    fprintf(fileID,'property float z\n');
    fprintf(fileID,'property uchar red\n');
    fprintf(fileID,'property uchar green\n');
    fprintf(fileID,'property uchar blue\n');
    fprintf(fileID,'end_header\n');
    for i=1:size(pts3d,1)
        fprintf(fileID,'%f %f %f %i %i %i\n',pts3d(i,1),pts3d(i,2),pts3d(i,3),r,g,b);
    end
    fclose(fileID);
end


例:
>> size(pts3d)

ans =

        3586           3

>> write3ply(pts3d,255,255,255);


GraphStudio 分割stereo 3D视频

2通道的视频,通过GraphStudio即可分割成两个独立视频。

例:分割一个fujifilm real3d w3 拍摄的3D视频。


再配合VirtualDub,就能提取出每一帧图片,用于后继处理。

GraphStudio 下载
VirtualDub 下载

Matlab label 转 color 显示

此方法将label[0...N]矩阵对应成随机色彩,便于观察。
如有label为0,则强制对应成黑色。

function [] = showLabels( L )
    unilabels = unique(L);
    NUM = length(unilabels);
    compactL = zeros(size(L));
    for i=1:NUM
        compactL(L==unilabels(i)) = i;
    end
    h = hsv(NUM);
    r = randperm(NUM);
    cmap = h(r,:);
    if(unilabels(1)==0)
        cmap(1,:) = [0 0 0];
    end
    figure; imshow(reshape(cmap(compactL,:),size(L,1),size(L,2),3));
end

例:

>> labels = magic(3)

labels =

     8     1     6
     3     5     7
     4     9     2

>> showLabels(imresize(labels,100,'nearest'));


Matlab 取得格式化文件名

function s = fileName(folder, k)
    s = num2str(k);
    blankNum = 4 - length(s);
    for i = 1: blankNum
         s = ['0', s];
    end
    s =  [folder, s, '.jpg'];
end


例:
>> f = fileName('C:\FUJun\data\ar\abc\',1)

f =

C:\FUJun\data\ar\abc\0001.jpg

张正友摄像头标定

    摄像头模型通常简化成小孔成像,再根据光的直线传播原理,很容易得到物象关系。然而,人们通常所说的针孔摄像头/机,用的并不是针孔镜头。针孔镜头是指利用小孔成像原理来得到影像的镜头,它造价低廉,原理简单,但是有一个致命的弱点:透过小孔的光线太少而导致曝光时间过长。在阳光下使用针孔镜头拍摄照片需要花几分钟到十几分钟,在夜晚拍摄时曝光时间则要达到几个小时。很显然,对于每秒钟要拍摄十几张到几十张的摄像机来说,是达不到要求的。

    所以取代小孔,现代摄像头加装了凸透镜头,利用凸透镜汇聚原理,使得采光面积大大增加,而又可以在cmos面上聚焦。由于透镜的折射,以及制造工艺的不足,不可避免图像扭曲具体表现在直线变成曲线,越往图像边缘失真越大。即便用多镜头组和,也难以根除。

    虽然现代摄像头失真已经很小,但是对于需要精度的领域,如双目视觉、增广现实,对所得图像还是要进行软件纠正,即摄像头标定(lens calibration)之内参。所谓内参,就是相对摄像头视场移动不变得参数,属于摄像头固有参数。

    具体推导过程参见:http://blog.csdn.net/onthewaysuccess/article/details/40736177

http://www.cnblogs.com/Akagi201/archive/2012/05/19/2509184.html

http://blog.csdn.net/sunanger_wang/article/details/7744025

http://blog.csdn.net/humanking7/article/details/44756073

opencv avi 转 jpg

#include "opencv2\highgui\highgui.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include <iostream>
#include <iomanip>

const std::string fileName = "C:\\FUJun\\data\\ar\\abc.avi";
const std::string dstFolder = "C:\\FUJun\\data\\ar\\abc\\";
const int newWidth = 860;
const int newHeight = 540;

int main(int argc, char* argv[])
{
cv::VideoCapture cap(fileName);
if (!cap.isOpened()){
std::cout << "!!! Failed to open file: " << fileName << std::endl;
return -1;
}

cv::Size size(newWidth,newHeight);
cv::Mat dst;

cv::Mat frame;
for(int i=0;;i++){
if (!cap.read(frame))          
break;

cv::resize(frame,dst,size);
cv::imshow("window", dst);
std::ostringstream ostr;
ostr << dstFolder << std::setfill('0') << std::setw(4) << i <<".jpg";
cv::imwrite(ostr.str(),dst);

char key = cvWaitKey(10);
if (key == 27) // ESC
break;
}

return 0;
}

双目图集 Stereo Images

conne

teddy

tsukuba

conne edge

The KITTI Vision Benchmark  http://www.cvlibs.net/datasets/kitti/index.php