Allen's Blog
Write down my life!
2022年10月2日 星期日
Blog has been migrated! 部落格搬家囉!
Hi, all,
This blog is not currently maintained.
Please move to https://blog.allenworkspace.net for getting my new posts.
大家好,本部落格已不再更新。請移駕到https://blog.allenworkspace.net 得到我更新的文章。
2021年4月7日 星期三
Logistics regression in Chinese
Here are recommended posts in Chinese for understanding logistics regressions. The readers can read them step by step.
1. 機器/統計學習: 羅吉斯回歸(Logistic regression), URL: https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8-%E7%B5%B1%E8%A8%88%E5%AD%B8%E7%BF%92-%E7%BE%85%E5%90%89%E6%96%AF%E5%9B%9E%E6%AD%B8-logistic-regression-aff7a830fb5d
2. 你可能不知道的邏輯回歸(Logistics Regression), URL: https://taweihuang.hpd.io/2017/12/22/logreg101/
2020年8月5日 星期三
科技的進步,學無止境
在2006年左右,我還在唸嘉義大學數學系時,跟同學分工合作,用PHP 5+Dreamweaver 寫學校處室網站,那時候學校IT不給MySQL/Sql Server,我自己還默默用很簡單的檔案系統處理函數,定義好資料結構,一行一行把「最新消息」等訊息,存在單一檔案作為offline database使用(那時候學藝不精,不知道有Sqlite可以用)。就這樣把學校處室的消息發布功能做了出來,還具備CRUD功能。
在那個大學年代,身兼學校的BBS系統站長,在那邊辛苦學習FreeBSD , Linux⋯當起MIS,三不五時就是去修伺服器,怎麼用fsck修硬碟, Make tools, build kernel 還自己去學怎麼剪RJ 45網路線,讓Server可以正常運作(可見那時候多窮,還要自己剪網路線)。
就這樣懵懵懂懂地大學畢業。
碩士班時期,實驗室還沒有積累一些關於data mining智慧資產,自己寫了一些演算法,像是PrefixSpan sequential pattern mining. 為了求效能,還全部用C++搭配STL寫。自己排crontab job,搭配bash script來產生自己要的實驗記錄。
博士班時期,老實說蠻精彩的。
當了三年的兼任助理,幫忙編hadoop教材...。為了自己的生計,還幫學校處室架設Wordpress,改別人的theme,甚至去看wordpress template怎麼寫,修掉別人模板的bug。也稍微懂得怎麼調整Apache的參數讓系統效能能夠跟得上來。
因為過去都用PHP寫網站,也順便接了幾個案子,像是做一些報名系統,多語系網站建置。
去當了幾家公司的兼任工程師,都是以C# + ASP.Net/MVC 作為主要工作技能。
曾經接了某個專利事務所的案子,幫別人寫Chrome外掛(後續做得不錯,顧客還有回鍋要我再幫忙開發,但是要顧學業,就婉拒了。)
曾幫博弈平台公司維護模組(這期間眼睛也去動手術了)。
為了打軟體競賽,還去用MongoDB,寫寫jQuery and Bootstrap。
為了做某公司的軟體專案,自己去玩Zebra ZPL印表機語言, WCF跟實作軟體序號與數位簽章演算法。
為了幫德國實驗室的同事做Big Data Benchmark,學怎麼用HBase & MapReduce API來做一些ETL工作(後來這也成為我的論文參考文獻之一)。
那時候政府還很流行Open Data,就去學架設CKAN,以及去研究HTTP協議,寫一些CKAN的prototype plugin。
出社會工作了,這些學到的技能也逐漸成為我的技術基石,不過是這些都是後話了。
2020年7月27日 星期一
Raspberry Pi Camera + OpenCV
If you are interested in how to use Raspberry Pi Camera + OpenCV to capture images, here is a great post in Chinese.
However, the post had something wrong. If you want to install OpenCV packages of Python 3, please use the command “apt-get install python3-opencv”.
標籤:
Python,
Raspberry Pi
2020年6月25日 星期四
FFMPEG: Decode and then encode frames to JPEG images
I've used FFMPEG library for a while. Actually, the FFMPEG library's decoding process flow can be described as the following picture. If you want to read the videos and then save to jpeg file, you can take a look on my programming code (tested on FFMPEG ver. 4 library).
// VideoProcessing.cpp // #pragma once using namespace std; #include <iostream> extern "C" { #include <libavcodec/avcodec.h> #include <libavdevice/avdevice.h> #include <libavformat/avformat.h> #include <libavfilter/avfilter.h> #include <libavutil/avutil.h> #include <libswscale/swscale.h> #pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avdevice.lib") #pragma comment(lib, "avformat.lib") #pragma comment(lib, "avfilter.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib, "swscale.lib") } void SaveToJPEG(AVFrame* pFrame, const char * folderName, int index) { // Setup Output Path char outFile[256] = { 0 }; sprintf_s(outFile, sizeof(outFile)/sizeof(outFile[0]), "%s\\OutputImages-%d.jpg", folderName, index); AVFormatContext* pFormatCtx = avformat_alloc_context(); // Setup the output format pFormatCtx->oformat = av_guess_format("mjpeg", NULL, NULL); // Initializext if (avio_open(&pFormatCtx->pb, outFile, AVIO_FLAG_READ_WRITE) < 0) { printf("Couldn't open output file."); return; } // Get a new Stream from the indicated format context AVStream* pAVStream = avformat_new_stream(pFormatCtx, 0); if (pAVStream == NULL) { return; } // Find encoder from the codec identifier. AVCodec* pCodec = avcodec_find_encoder(pFormatCtx->oformat->video_codec); if (!pCodec) { printf("Codec not found."); return; } // Setup the codec context AVCodecContext* codecCtx = avcodec_alloc_context3(pCodec); codecCtx->codec_id = pFormatCtx->oformat->video_codec; codecCtx->codec_type = AVMEDIA_TYPE_VIDEO; codecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P; codecCtx->width = pFrame->width; codecCtx->height = pFrame->height; codecCtx->time_base = AVRational{ 1,25 }; // Open the codec if (avcodec_open2(codecCtx, pCodec, NULL) < 0) { printf("Could not open codec."); return; } // assign the codec context to the stream parameters. avcodec_parameters_from_context(pAVStream->codecpar, codecCtx); //Write Header avformat_write_header(pFormatCtx, NULL); int y_size = (codecCtx->width) * (codecCtx->height); // assign large enough space AVPacket pkt; av_new_packet(&pkt, y_size); int got_picture = 0; // Use avcodec_send_frame()/avcodec_receive_packet() instead int ret = avcodec_send_frame(codecCtx, pFrame); if (ret < 0) { printf("Encode Error.\n"); return; } else { ret = avcodec_receive_packet(codecCtx, &pkt); ret = av_write_frame(pFormatCtx, &pkt); } av_packet_unref(&pkt); //Write Trailer av_write_trailer(pFormatCtx); printf("Encode Successful.\n"); avcodec_close(codecCtx); avio_close(pFormatCtx->pb); avformat_free_context(pFormatCtx); avcodec_free_context(&codecCtx); } int main(int argc, char * argv[]) { if (argc < 2) { cout << "You need to specify a media file." << endl; cout << "Command line : VideoProcessing.exe [input_video_path] [output_folder]" << endl; return -1; } AVFormatContext* pFormatContext = avformat_alloc_context(); if (!pFormatContext) { cout << "ERROR could not allocate memory for Format Context" << endl; return -1; } if (avformat_open_input(&pFormatContext, argv[1], NULL, NULL) != 0) { cout << "ERROR could not open the file" << endl; return -1; } if (avformat_find_stream_info(pFormatContext, NULL) < 0) { cout << "ERROR could not get the stream info" << endl; return -1; } // Initialize the codec, paramters for subsequent useage. AVCodec* pCodec = NULL; AVCodecParameters* pCodecParameters = NULL; int videoStreamIndex = -1; for (int i = 0; i < pFormatContext->nb_streams; i++) { AVCodecParameters* pLocalCodecParameters = NULL; // Read the codec parameters corresponding to each stream. pLocalCodecParameters = pFormatContext->streams[i]->codecpar; AVCodec* pLocalCodec = NULL; pLocalCodec = avcodec_find_decoder(pLocalCodecParameters->codec_id); if (pLocalCodec == NULL) { cout << "[ERROR] Cannot find the codec" << endl; } if (pLocalCodecParameters->codec_type == AVMEDIA_TYPE_VIDEO) { if (videoStreamIndex == -1) { videoStreamIndex = i; pCodec = pLocalCodec; pCodecParameters = pLocalCodecParameters; } } } AVCodecContext* pCodecContext = avcodec_alloc_context3(pCodec); if (pCodecContext == NULL) { cout << "Fail to allocate the memoery to the Codec Context." << endl; return -1; } if (avcodec_parameters_to_context(pCodecContext, pCodecParameters) < 0) { cout << "failed to copy codec params to codec context" << endl; return -1; } if (avcodec_open2(pCodecContext, pCodec, NULL) < 0) { cout << "failed to open codec through avcodec_open2" << endl; return -1; } AVFrame* pFrame = av_frame_alloc(); if (!pFrame) { cout << "failed to allocated memory for AVFrame" << endl; return -1; } AVPacket* pPacket = av_packet_alloc(); if (!pPacket) { cout << "failed to allocated memory for AVPacket" << endl; return -1; } int indexOfFrame = 0; while (av_read_frame(pFormatContext, pPacket) >= 0) { // if it's the video stream if (pPacket->stream_index == videoStreamIndex) { int response = avcodec_send_packet(pCodecContext, pPacket); if (response < 0) { break; } else { response = avcodec_receive_frame(pCodecContext, pFrame); if (response >= 0) { indexOfFrame++; SaveToJPEG(pFrame, argv[2], indexOfFrame); } } } av_packet_unref(pPacket); // Limit the number of output frame to be 5. if (indexOfFrame == 5) { break; } } // https://ffmpeg.org/doxygen/trunk/group__lavc__packet.html#ga63d5a489b419bd5d45cfd09091cbcbc2 avformat_close_input(&pFormatContext); av_frame_free(&pFrame); avcodec_free_context(&pCodecContext); }Reference:
2020年5月2日 星期六
The introduction for JavaScript ES6’s classes
Do not understand the class features of JavaScript ES6?
You can take a look on this introduction in Chinese.
標籤:
JavaScript
Speed up ActiveMQ performance by 25x
Sometimes we encounter the performance issue for persistent messaging using ActiveMQ.
Here’s the best practice on Linux system to accelerate it.
標籤:
ActiveMQ
2018年12月24日 星期一
Materials for Neural Network
Some materials are enclosed here.
1. 深度學習(二): 反向傳播 URL:http://chansh518.github.io/deep%20learning/2016/08/08/Deep-Learning-Notes-Backpropagation.html
2. 一文看懂常用的梯度下降算法 URL: https://blog.csdn.net/u013709270/article/details/78667531
3. 邏輯回歸代價函數及其梯度下降公式 URL: https://blog.csdn.net/Mr_HHH/article/details/78934793
4. The Back Propagation Algorithm. URL: https://page.mi.fu-berlin.de/rojas/neural/chapter/K7.pdf
5. Derivation of Back Propagation Algorithm for Forward Neural Networks. URL: http://www.cs.put.poznan.pl/pliskowski/pub/teaching/eio/lab1/eio-supplementary.pdf
6. 凸優化 梯度下降。URL: http://www.hanlongfei.com/凸优化/2015/09/29/cmu-10725-gradient/
7. Geadient Descent demystified. URL: https://towardsdatascience.com/gradient-descent-demystified-bc30b26e432a
8. An introduction to gradient descent and linear regression. URL: https://spin.atomicobject.com/2014/06/24/gradient-descent-linear-regression/
1. 深度學習(二): 反向傳播 URL:http://chansh518.github.io/deep%20learning/2016/08/08/Deep-Learning-Notes-Backpropagation.html
2. 一文看懂常用的梯度下降算法 URL: https://blog.csdn.net/u013709270/article/details/78667531
3. 邏輯回歸代價函數及其梯度下降公式 URL: https://blog.csdn.net/Mr_HHH/article/details/78934793
4. The Back Propagation Algorithm. URL: https://page.mi.fu-berlin.de/rojas/neural/chapter/K7.pdf
5. Derivation of Back Propagation Algorithm for Forward Neural Networks. URL: http://www.cs.put.poznan.pl/pliskowski/pub/teaching/eio/lab1/eio-supplementary.pdf
6. 凸優化 梯度下降。URL: http://www.hanlongfei.com/凸优化/2015/09/29/cmu-10725-gradient/
7. Geadient Descent demystified. URL: https://towardsdatascience.com/gradient-descent-demystified-bc30b26e432a
8. An introduction to gradient descent and linear regression. URL: https://spin.atomicobject.com/2014/06/24/gradient-descent-linear-regression/
訂閱:
文章 (Atom)