由於英文太爛,光靠wiki-Overfitting還是不太行,
不過google到這篇其實就寫的滿清楚的。
先從Machine Learning的角度去看Learning這件事,如果今天你記錄的你們班上所有人的身高和體重,
並且希望你給電腦身高,他就可以給你體重。
通常電腦就是把這些data(身高、體重)做一個linear regression,找出一條直接去fit這些data,
就像是我們假設身高和體重有線性關係,即身高愈高,體重愈重(或相反)。
但我們知道其實人的身高和體重不完全都符合這種關係,也就是有人很高卻很輕,有人很矮卻很重。
所以我們就想要用一條更符合這些data的曲線去fit這些data,讓這些data都在這條曲線上,
但這邊會發現,當我們利用了這些data找出這條很棒的曲線時,並且丟入其他班同學的身高去預測體重,
會產生完全離譜的體重,而且這條曲線會看不出身高和體重有線性的關係(照理說應該要接近線性)。
這個現象給我們一個想法: 不一定要把目前已知的東西用太複雜的想法去解釋。
另外剛剛google到的那篇也有提到一個人說過的話:
Occam's Razor Principle,中文是奧卡姆剃刀原則(怎麼有點想刮鬍子..)
「One should proceed to simpler theories until simplicity can be traded for greater explanatory power.」
「切勿浪費較多東西,去做『用較少的東西,同樣可以做好的事情』」
2013年4月29日 星期一
2013年4月28日 星期日
Include DLL path in VS2010
1. Go to project properties (Alt+F7)
2. Under Debugging, look to the right
3. There's an Environment field.
4. Add your relative path there (relative to vcproj folder) i.e. ..\some-framework\lib by appending PATH=%PATH%;$(ProjectDir)\some-framework\lib or prepending to the path PATH=C:\some-framework\lib;%PATH%
5. Hit F5 (debug) again and it should work.
ref:
http://stackoverflow.com/questions/2119539/visual-studio-how-to-set-path-to-dll
2. Under Debugging, look to the right
3. There's an Environment field.
4. Add your relative path there (relative to vcproj folder) i.e. ..\some-framework\lib by appending PATH=%PATH%;$(ProjectDir)\some-framework\lib or prepending to the path PATH=C:\some-framework\lib;%PATH%
5. Hit F5 (debug) again and it should work.
ref:
http://stackoverflow.com/questions/2119539/visual-studio-how-to-set-path-to-dll
2013年4月25日 星期四
OpenCV on iOS with Xcode - Convert between UIImage, CvMat and IplImage
通常IplImage和CvMat 在 3 channels下的data,都是以BGR的方式排列的
例:
正常來說應該是這樣子把IplImage的資料複製到cvMat底下,但我經過了以上的code後,在把cvMat透過以下的方式轉到UIImage,卻發現顏色跑掉。
所以我試著把BGR的位置對調,如下:
是的! 可能是CvMat 轉UIImage時,把他看成RGB的排列方式轉了吧!?(不確定)
但使用上列方式,顏色就正常了。
最後在丟一些convert的code:
UIImage to CvMat:
UIImage to IplImage:
IplImage to UIImage:
ref:
https://sites.google.com/site/iprinceps/Home/iphone-1/converting-images-between-uiimage-and-iplimage
http://code.opencv.org/svn/gsoc2012/ios/trunk/ImageFilter/ImageFilter/UIImageCVMatConverter.mm
例:
IplImage *img = cvCreateImage(cvSize(imageWidth, imageHeight),IPL_DEPTH_8U,3);
cv::Mat imgMat(imagewidth, imageHeight, CV_8UC3);
for (int j=0; j<imageHeight; j++){
for (int i=0; i<imageWidth; i++){
imgMat.data[j*imgMat.widthStep+i*imgMat.nChannels] = img->imageData[j*img->widthStep+i*nChannels]; // B
imgMat.data[j*imgMat.widthStep+i*imgMat.nChannels+1] = img->imageData[j*img->widthStep+i*nChannels+1]; // G
imgMat.data[j*imgMat.widthStep+i*imgMat.nChannels+2] = img->imageData[j*img->widthStep+i*nChannels+2]; // R
}
}
正常來說應該是這樣子把IplImage的資料複製到cvMat底下,但我經過了以上的code後,在把cvMat透過以下的方式轉到UIImage,卻發現顏色跑掉。
+(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorSpace;
if (cvMat.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
bool alpha = cvMat.channels() == 4;
CGBitmapInfo bitMapInfo = (alpha ? kCGImageAlphaLast : kCGImageAlphaNone) | kCGBitmapByteOrderDefault;
// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
cvMat.rows, //height
8, //bits per component
8 * cvMat.elemSize(), //bits per pixel
cvMat.step[0], //bytesPerRow
colorSpace, //colorspace
bitMapInfo, // bitmap info
provider, //CGDataProviderRef
NULL, //decode
false, //should interpolate
kCGRenderingIntentDefault //intent
);
// Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return finalImage;
}
所以我試著把BGR的位置對調,如下:
IplImage *img = cvCreateImage(cvSize(imageWidth, imageHeight),IPL_DEPTH_8U,3);
cv::Mat imgMat(imagewidth, imageHeight, CV_8UC3);
for (int j=0; j<imageHeight; j++){
for (int i=0; i<imageWidth; i++){
imgMat.data[j*imgMat.widthStep+i*imgMat.nChannels+2] = img->imageData[j*img->widthStep+i*nChannels]; // B
imgMat.data[j*imgMat.widthStep+i*imgMat.nChannels+1] = img->imageData[j*img->widthStep+i*nChannels+1]; // G
imgMat.data[j*imgMat.widthStep+i*imgMat.nChannels] = img->imageData[j*img->widthStep+i*nChannels+2]; // R
}
}
是的! 可能是CvMat 轉UIImage時,把他看成RGB的排列方式轉了吧!?(不確定)
但使用上列方式,顏色就正常了。
最後在丟一些convert的code:
UIImage to CvMat:
+ (cv::Mat)cvMatFromUIImage:(UIImage *)image
{
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
CGFloat cols = image.size.width;
CGFloat rows = image.size.height;
cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
cols, // Width of bitmap
rows, // Height of bitmap
8, // Bits per component
cvMat.step[0], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrderDefault); // Bitmap info flags
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
CGContextRelease(contextRef);
// CGColorSpaceRelease(colorSpace);
return cvMat;
}
+ (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image
{
cv::Mat cvMat = [UIImageCVMatConverter cvMatFromUIImage:image];
cv::Mat grayMat;
if (cvMat.channels() == 1) {
grayMat = cvMat;
} else{
grayMat = cv :: Mat(cvMat.rows,cvMat.cols, CV_8UC1);
cv::cvtColor(cvMat, grayMat, CV_BGR2GRAY);
}
return grayMat;
}
UIImage to IplImage:
// NOTE you SHOULD cvReleaseImage() for the return value when end of the code.
- (IplImage *)CreateIplImageFromUIImage:(UIImage *)image {
// Getting CGImage from UIImage
CGImageRef imageRef = image.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Creating temporal IplImage for drawing
IplImage *iplimage = cvCreateImage(
cvSize(image.size.width,image.size.height), IPL_DEPTH_8U, 4
);
// Creating CGContext for temporal IplImage
CGContextRef contextRef = CGBitmapContextCreate(
iplimage->imageData, iplimage->width, iplimage->height,
iplimage->depth, iplimage->widthStep,
colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault
);
// Drawing CGImage to CGContext
CGContextDrawImage(
contextRef,
CGRectMake(0, 0, image.size.width, image.size.height),
imageRef
);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
// Creating result IplImage
IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 3);
cvCvtColor(iplimage, ret, CV_RGBA2BGR);
cvReleaseImage(&iplimage);
return ret;
}
IplImage to UIImage:
// NOTE You should convert color mode as RGB before passing to this function
- (UIImage *)UIImageFromIplImage:(IplImage *)image {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Allocating the buffer for CGImage
NSData *data =
[NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider =
CGDataProviderCreateWithCFData((CFDataRef)data);
// Creating CGImage from chunk of IplImage
CGImageRef imageRef = CGImageCreate(
image->width, image->height,
image->depth, image->depth * image->nChannels, image->widthStep,
colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault,
provider, NULL, false, kCGRenderingIntentDefault
);
// Getting UIImage from CGImage
UIImage *ret = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ret;
}
ref:
https://sites.google.com/site/iprinceps/Home/iphone-1/converting-images-between-uiimage-and-iplimage
http://code.opencv.org/svn/gsoc2012/ios/trunk/ImageFilter/ImageFilter/UIImageCVMatConverter.mm
2013年4月24日 星期三
OpenCV - image->imagdata[j*widthStep+i] v.s. cvSet2D(image, j, i, CvScalar)
用cvGet2D()的方式,CvScalar的值如果超過255,會被歸成255。
但用image->imagedata讀資料的話,超過255的值會被扣掉255,
例: 存300,就會變300-256= 44
另外如果用image->imagedata讀資料,做資料的加減乘除,建議轉成double做,而且要先轉unsigned,
例:
因為image->imagadata為char,
假如image->imagedata[j*widthStep+i]的值為10000000(二進位)
那麼在十進位會看成-128,(double)image->imagedata[j*widthStep+i] = -128.0,
但其實在image裡值是0~255,所以他其實表示的值是+128,因此我們要先取unsigned,再取double。
另外若是兩個值相加完除2.0f不整除,用cvSet2D會四捨五入,直接用imagedata會無條件捨去,
例:
但用image->imagedata讀資料的話,超過255的值會被扣掉255,
例: 存300,就會變300-256= 44
另外如果用image->imagedata讀資料,做資料的加減乘除,建議轉成double做,而且要先轉unsigned,
例:
double temp1 = (double)(uchar)image->imagedata[j*widthStep+i+1];
double temp2 = (double)(uchar)image->imagedata[j*widthStep+i+2];
image->imagedata[j*widthStep+i] = (temp1+temp2)/2.0f;
因為image->imagadata為char,
假如image->imagedata[j*widthStep+i]的值為10000000(二進位)
那麼在十進位會看成-128,(double)image->imagedata[j*widthStep+i] = -128.0,
但其實在image裡值是0~255,所以他其實表示的值是+128,因此我們要先取unsigned,再取double。
另外若是兩個值相加完除2.0f不整除,用cvSet2D會四捨五入,直接用imagedata會無條件捨去,
例:
//(255+100)/2 = 177.5
cvSet2D(img, j, i, cvScalarAll((255+100)/2.0f));
// 上面這行的值會丟 178
image->imagedata[j*widthStep+i] = (255+100)/2.0f;
// 上面這行的值會丟 177
2013年4月22日 星期一
OpenCV - cvGet2D() and cvSet2D()
一般數學上我們都以(i, j)表示成 x = i, y = j
但OpenCV裡cvGet2D和cvSet2D的第一、二個參數(idx0, idx1)卻不是這個意思,
以數學方式來看的話是指(idx1, idx0),因為以程式設計中讀取一維陣列是
「有幾個row」乘上「img的寬度」加上「最後一列中的第幾個」
= idx0 * img->width + idx1
cvGet2D(source image, colume-th, row-th)
CODE:
但OpenCV裡cvGet2D和cvSet2D的第一、二個參數(idx0, idx1)卻不是這個意思,
以數學方式來看的話是指(idx1, idx0),因為以程式設計中讀取一維陣列是
「有幾個row」乘上「img的寬度」加上「最後一列中的第幾個」
= idx0 * img->width + idx1
cvGet2D(source image, colume-th, row-th)
CODE:
for(int j=0; j<height; j++){
for(int i=0; i<width; i++){
CvScalar scalar_old = cvGet2D(img, j, i);
// 抓出img(i, j)的 pixel值
CvScalar scalar_new = cvScalarAll(scalar_old.val[0]);
// 把img(i, j).b值 設成新的scalar的bgr值
cvSet2D(img, j, i, scalar_new);
// 把新的scalar丟回img
}
}
2013年4月21日 星期日
Xiapin蝦拼 字根檔莫名消失 on iPhone5 with ios 6.1.2
今天為了把平常常打的字根檔加到我的iphone5,卻發生了一些問題
原本字根檔的排序如下:
不管怎麼樣重新匯入,都會導致這個問題,於是我google了一下,看到以下連結:
http://xiapin.wordpress.com/main/
決定試一下把sqlite全部清掉,再重新匯入一次。沒想到神奇的事情發生了…
一開始匯入的時候我是看不到任何使用者字典的,但過了一會…原先我設定的字典就回來了!!!
我想這可能是icloud在同步的過程中發生了什麼狀況吧…
原本字根檔的排序如下:
------------ a 對 aa 寸 aaa 鑫 … aaom 鑰 ------------但更改後的字根檔重新匯入完,一開始一樣會看到前面幾項,但過了一會會變成下列情況:
------------ aaom 鑰 … ------------也就是前面幾個字莫明奇妙就消失了,導致我不能打"對"…
不管怎麼樣重新匯入,都會導致這個問題,於是我google了一下,看到以下連結:
http://xiapin.wordpress.com/main/
決定試一下把sqlite全部清掉,再重新匯入一次。沒想到神奇的事情發生了…
一開始匯入的時候我是看不到任何使用者字典的,但過了一會…原先我設定的字典就回來了!!!
我想這可能是icloud在同步的過程中發生了什麼狀況吧…
2013年4月18日 星期四
C++ Random a float number between 0~1
(float) rand() / RAND_MAX;
// RAND_MAX = 0x7fffffff
因為rand的值在0~0x7fffffff,所以直接除RAND_MAX再取float就得0~1之間的浮點數
訂閱:
文章 (Atom)