Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Image processing using OpenCV and multi-threads. #1

Merged
merged 5 commits into from
Dec 22, 2016

Conversation

qingqing01
Copy link
Collaborator

@qingqing01 qingqing01 commented Dec 14, 2016

可供Paddle的PyDataProvider调用的图像处理库, 这个库目前支持功能:

  1. 提供了python调用接口, 目前还采用Boost.Python @reyoung 因为不在Paddle住代码库,目前还想继续采用Boost.Python, 以后可以再去掉, 你看这样可否?
  2. 支持多线程处理
  3. 支持resize + random crop + flipping。

后续会继续加其他data argumentation,所以比较希望这部分先merge进去,方便持续开发。

有一个问题是: 采用 @reyoung 推荐的ThreadPool, 即: https://github.com/progschj/ThreadPool
该PR的ThreadPool.h的copyright加的是: https://github.com/progschj/ThreadPool/blob/master/COPYING
不知道这样可否?

capacity_(capacity),
threadPool_(threadNum),
prefetchQueue_(capacity) {
fetchCount_ = -1;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

放到init list里面

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

重构后去掉了该参数~


int main(int argc, char** argv) {
float mean[3] = {103.939, 116.779, 123.68};
DataTransformer* trans = new DataTransformer(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没有free
不要用new

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改成了Python代码单测,这个文件删掉了。

int main(int argc, char** argv) {
float mean[3] = {103.939, 116.779, 123.68};
DataTransformer* trans = new DataTransformer(
4, 1024, false, true, 224, 224, 256, false, true, mean);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参数过多了。一般这种情况,我们会写一个DataTransformConfig的POD

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

float mean[3] = {103.939, 116.779, 123.68};
DataTransformer* trans = new DataTransformer(
4, 1024, false, true, 224, 224, 256, false, true, mean);
std::string src = argv[1];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unittest还是用gtest吧,扩展起来方便。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改成了Python代码单测~

@@ -0,0 +1,108 @@
/* Copyright (c) 2012 Jakob Progsch, Václav Zeman
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新建一个

third_patry目录,然后git submoudle对方的版本库,不要copy进来。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done~


void DataTransformer::obtain(float* data, int* label) {
if (fetchId_ >= fetchCount_) {
LOG(FATAL) << "Empty data";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

返回值,bool。 true成功,false失败。

if (fetchId_ >= fetchCount_) {
LOG(FATAL) << "Empty data";
}
DataTypePtr ret = results_[fetchId_].get();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dequeue

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

DataTypePtr ret = results_[fetchId_].get();
*label = ret->second;
memcpy(data, ret->first, sizeof(float) * imgPixels_);
prefetchQueue_.enqueue(ret);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其实感觉obtain直接返回float* 效果更好吧?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已重构,使用Boost.Numpy。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已重构,使用Boost.Numpy。

* @param filename The file name.
* @param im The image to be saved.
*/
void imsave(std::string filename, cv::Mat& im) { cv::imwrite(filename, im); }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* @param img The input image Mat to be transformed.
* @param target target is used to save the transformed data.
*/
void transform(cv::Mat& img, float* target);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cv::Mat& => const cv::Mat&

如果是复杂类型,要么是 const Blah&(只读),要么是Blah*(读写)

参考 https://www.zhihu.com/question/20132622/answer/22302151

@qingqing01
Copy link
Collaborator Author

@reyoung Thanks for your review :)


find_package(PythonLibs 2.7 REQUIRED)
find_package(PythonInterp 2.7 REQUIRED)
find_package(Glog)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看起来glog也应该是REQUIRED的吧?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

int DataTransformer::Rand(int min, int max) const {
std::mt19937 rng(time(0));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

random这个搞,每次都调用一个time(0),似乎会比较慢。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class Random {
public:
    Random() {
        ...
    }

    int randInt(int min, int max) const {
       std::uniform_int_dist<int> dist(min, max);
       return dist(eng);
    }
private:
    std::default_random_engine eng;
};

Copy link
Collaborator Author

@qingqing01 qingqing01 Dec 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用了 std::default_random_engine eng, 但是没有单独写个class, 或许下个PR需要添加其他随机数产生时,再单独提出来。

float scale = config_->scale_;
float* meanVal = config_->meanValues_;
for (int h = 0; h < height; ++h) {
const uchar* ptr = cv_cropped_img.ptr<uchar>(h);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uchar => uint8_t ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uchar也可以

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint8_t在标准库里面,uchar应该不在。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

void DataTransformer::transform(cv::Mat& cvImgOri, float* target) const {
const int imgChannels = cvImgOri.channels();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看起来这个函数是很多操作的集合,可否把这些操作注释一下或者独立成几个函数。

// crop

// sub mean.

// etc

Copy link
Collaborator Author

@qingqing01 qingqing01 Dec 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

下个PR添加更多data argumentation操作时再拆分吧。

T(T const&) = delete; \
void operator=(T const& t) = delete

typedef enum { CHANNEL_MEAN = 0, ELEMENT_MEAN = 1, NULL_MEAN = 2 } MeanType;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum MeanType {...};

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/**
* @brief Check whether the PyObject is writable or not.
*/
void pyWritableCheck(PyObject* o) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这几个check用上了么?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没有用到,已删除。

@@ -0,0 +1,4 @@
add_test(NAME test_dejpeg
COMMAND ${PROJ_ROOT}/.set_python_path.sh -d ${CMAKE_CURRENT_BINARY_DIR}/../.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${CMAKE_CURRENT_BINARY_DIR}/../. =>${CMAKE_CURRENT_BINARY_DIR}/..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

try {
cv::Mat im = cv::imread(imgFile, cvFlag);
if (!im.data) {
LOG(ERROR) << "Could not decode image";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOG(ERROR) => LOG(FATAL) ?

不是特别理解这里的是不是要程序core掉。如果不core掉,似乎trg里面的数据就是错的了。如果core掉,那似乎应该用LOG(FATAL)。如果想做容忍错误,应该用返回值之类的东西。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原意想容错,更改后去掉了try catch, 改成了LOG(FATAL) ,不允许不符合规范的图片,比如gif图片。

}

int DataTransformer::rand(int min, int max) const {
std::default_random_engine eng;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这么搞会慢啊亲。。为啥不改一下啊。。

另外,这么改完了,似乎每次的随机值都一样了?因为random_engine不会初始化随机种子吧??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

将 std::default_random_engine eng 移到class里面~

float scale = config_->scale_;
float* meanVal = config_->meanValues_;
for (int h = 0; h < height; ++h) {
const uchar* ptr = cv_cropped_img.ptr<uchar>(h);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint8_t在标准库里面,uchar应该不在。

Copy link

@reyoung reyoung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically LGTM, except the argument passing style. Please fix them if you want.

* @param img The input image Mat to be transformed.
* @param target target is used to save the transformed data.
*/
void transform(cv::Mat& img, float* target);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cv::Mat& => const cv::Mat&

如果是复杂类型,要么是 const Blah&(只读),要么是Blah*(读写)

参考 https://www.zhihu.com/question/20132622/answer/22302151

* @param filename The file name.
* @param im The image to be saved.
*/
void imsave(std::string filename, cv::Mat& im) const {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


~Parallel() {}

int start(boost::python::list& pysrc, PyObject* pylabel, int mode) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@qingqing01 qingqing01 merged commit 397ec9e into PaddlePaddle:master Dec 22, 2016
@qingqing01
Copy link
Collaborator Author

argument passing style 下个PR会一起修改~

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants