pip install scikit-image

原文

brew install opencv

echo /usr/local/opt/opencv/lib/python3.7/site-packages >> /usr/local/lib/python3.6/site-packages/opencv3.pth

pip install numpy scipy scikit-image matplotlib scikit-learn

cd ~/.virtualenvs/cv-py3/lib/python3.7/site-packages/
ln -s /usr/local/opt/opencv@3/lib/python3.7/site-packages/cv2.cpython-37m-darwin.so cv2.so

编译

查看 install 文件, 使用 cmake 导出 vs2015 工程,然后编译

下载例子项目

git clone --depth=1 https://github.com/imatix/zguide.git

pub-sub example

auto pzmq_ctx_new = g_dllzmq.getDllFunc<void*()>("zmq_ctx_new");
auto pzmq_socket = g_dllzmq.getDllFunc<void*(void *context, int type)>("zmq_socket");
auto pzmq_bind = g_dllzmq.getDllFunc<int(void *socket, const char *endpoint)>("zmq_bind");
auto pzmq_recv = g_dllzmq.getDllFunc<int(void *socket, void *buf, size_t len, int flags)>("zmq_recv");
auto pzmq_send = g_dllzmq.getDllFunc<int(void *socket, void *buf, size_t len, int flags)>("zmq_send");
auto pzmq_close = g_dllzmq.getDllFunc<int(void *socket)>("zmq_close");
auto pzmq_ctx_destroy = g_dllzmq.getDllFunc<int(void *context)>("zmq_ctx_destroy");
auto pzmq_setsockopt = g_dllzmq.getDllFunc<int(void *socket, int option_name, const void *option_value, size_t option_len)>("zmq_setsockopt");


// Prepare our context and publisher
void* pCtx = pzmq_ctx_new();
// Socket to talk to clients
void *publisher = pzmq_socket(pCtx, ZMQ_PUB);
int rc = pzmq_bind(publisher, "tcp://*:5563");
assert(rc == 0);

while (FLAG_EXIT_WORKTHREAD != (pwnd->m_iFlag&FLAG_EXIT_WORKTHREAD))
{
// broadcast information.
pzmq_send(publisher, "A", 1, ZMQ_SNDMORE);
pzmq_send(publisher, "Hi World", strlen("Hi World"), 0);

pzmq_send(publisher, "B", 1, ZMQ_SNDMORE);
pzmq_send(publisher, "Hello World", strlen("Hello World"), 0);

Sleep(3000);
}
pzmq_close(publisher);
pzmq_ctx_destroy(pCtx);

讲了常见的形态,还算可以吧。

20190603_203929.png

命名管道

使用 process explorer search - handle or dll
输入 \Device\NamedPipe\ 点击search,就可以了

共享内存

Socket

WM_COPYDATA

使用WM_COPYDATA消息通信
对于少量数据可以用WM_COPYDATA方便地实现通信。由于SendMessage()是阻塞的,只有接收方响应了消息,SendMessage()才能返回,否则一直阻塞。所以,对于大量数据来说,用SendMessage()就容易造成窗口假死。

在Win32中,WM_COPYDATA消息主要目的是允许在进程间传递只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。这个函数的原型如下:

SendMessage(WM_COPYDATA,wParam,lParam)

// 其中wParam设置为包含数据的窗口句柄,lParam指向一个COPYDATASTRUCT的结构,其定义为:

typedef struct tagCOPYDATASTRUCT{
DWORD dwData;
DWORD cbData;
PVOID lpData;
}COPYDATASTRUCT;

其中dwData为自定义数据, cbData为数据大小, lpData为指向数据的指针。需要注意的是,WM_COPYDATA消息保证发送的数据从原进程复制到目标进程。但是,WM_COPYDATA消息不能发送HDC、HBITMAP之类的东西,它们对于目标进程来说是无效的。目标进程得到这些数据不能在原进程作任何事情,因为它们属于不同的进程。

与其他进程通信方法一样,要实现进程间的数据通信,在发送数据的程序中,首先要找到接收数据进程的窗口句柄pWnd,可以用CWnd::FindWindow(NULL,_ T(“DataRecv”))函数来得到,其中字符串”DataRecv”为接收数据的程序名。然后用SendMessage()函数发送数据,其具体的做法见后面的实例。

在接收数据的程序中,首先在消息映射表中增加WM_COPYDATA消息映射,然后定义消息映射函数,其函数的格式为:

BOOL CDataRecvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
// 增加用户自定义程序代码

}

通过WM_COPYDATA消息实现进程间通信的实例
与前面所说的自定义消息不一样,WM_COPYDATA消息是Win32提供的消息。与自定义消息相比较,WM_COPYDATA消息可以传递一个较大的数据块。这里仍然用两个对话框程序来实现WM_COPYDATA消息的通信。

以下分别给出发送数据程序的发送函数和接收数据程序的接收函数。在发送数据的对话框类CDataSendDlg中,用MFC ClassWizard工具或者手工的方法增加函数void CDataSendDlg::OnSendCopydata(),其具体代码如下:

void CDataSendDlg::OnSendCopydata()
{
UpdateData(); // 更新数据
CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv")); // 查找DataRecv进程
if(pWnd==NULL){
AfxMessageBox("Unable to find DataRecv.");
return;
}
COPYDATASTRUCT cpd; // 给COPYDATASTRUCT结构赋值
cpd.dwData = 0;
cpd.cbData = m_strCopyData.GetLength();
cpd.lpData = (void*)m_strCopyData.GetBuffer(cpd.cbData);
pWnd->SendMessage(WM_COPYDATA,NULL,(LPARAM)&cpd); // 发送
}

在用MFC AppWizard(exe)创建接收数据的对话框程序后,生成对话框类CDataRecvDlg。在这个类中,首先要定义接收 WM_COPYDATA 消息的映射,可以用ClassWizard工具来增加,也可以手动增加,但手动增加需要修改三个地方:①在消息映射表中增加 ON_WM_COPYDATA();②增加成员函数BOOL CDataRecvDlg::OnCopyData();③在CDataRecvDlg类中增加WM_COPYDATA消息映射函数的定义。

WM_COPYDATA消息的映射如下:

BEGIN_MESSAGE_MAP(CDataRecvDlg, CDialog)
//{{AFX_MSG_MAP(CDataRecvDlg)
ON_WM_COPYDATA()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CDataRecvDlg::OnCopyData()函数的定义如下:

BOOL CDataRecvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
m_strCopyData=(LPSTR)pCopyDataStruct->lpData;
// 获得实际长度的字符串
m_strCopyData=m_strCopyData.Left(pCopyDataStruct->cbData);
// 更新数据
UpdateData(FALSE);
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

其中m_strCopyData为接收到的字符串,pCopyDataStruct为COPYDATASTRUCT结构指针。注意由pCopyDataStruct直接得到的m_strCopyData字符串长度可能不是实际发送的字符串长度,需要用发送字符串时所给定的字符串长度来进一步确定,其长度由pCopyDataStruct ->cbData来得到。

这本书基本上就是举了大量的例子来说明应该逆向思考,理性的,有依据的的判断很重要。

20190603_072743.png

#x

#container {
width: 960px;
margin: auto;
}

在选择器中使用#可以用id来定位某个元素。大家通常都会这么使用,然后使用的时候大家还是得相当小心的。需要问自己一下:我是不是必须要给这个元素来赋值个id来定位它呢?
id选择器是很严格的并且你没办法去复用它。如果可能的话,首先试试用标签名字,HTML5中的新元素,或者是伪类。

.x

.error {
color: red;
}

class 选择器用于描述一组元素的样式,class 选择器有别于id选择器,class可以在多个元素中使用。

选择 td

/* 最后一列 */
#main_tbody tr td:last-child{
padding-top: 5px;
}

/* 指定列 */
#main_tbody tr td:nth-child(3){
padding-top: 5px;
}

生成 requirements.txt 文件

pip freeze > requirements.txt

安装 requirements.txt 依赖

pip install -r requirements.txt

标签

定义导航链接的部分。也利于 seo

<nav><a>首页</a><a>文章</a><a>关于</a></nav>    

ul

无序 HTML 列表:

<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>

tr th td

tr 表示一行
th 表示表头
td 表示一列

a href

指向 w3school 的超链接:

<a href="http://www.w3school.com.cn">W3School</a>

官网

介绍

Echarts 是百度可视化工具,pyecharts 是一个用于生成 Echarts 图表的类库。

install

pip install pyecharts

203,2110,2569,1008,94

测试环境:               

error_reporting = E_ALL
display_errors = On
html_errors = On
log_errors = Off

正式环境:

error_reporting = E_ALL & ~E_NOTICE
display_errors = Off
log_errors = On
html_errors = Off
error_log = “/var/log/php-error.log”
ignore_repeated_errors = On
ignore_repeated_source = On