Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

segmentation #227

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ before_install:

# origin weights are from https://github.com/NifTK/NiftyNetModelZoo/tree/5-reorganising-with-lfs/unet_histology
- megadl 'https://mega.nz/#!RAFU1I4T!xjuol1lZ9t_hA67AxgAxp8w1JIb5FXm53617UXR0NO8' --path data --no-progress # frozen_unet_histology.pb
# TODO: Implement frozen_unet_histology.pb model conversion with OpenVINO
# (note that TensorFlow accepts input tensor of shape 1,952,1144,1,1,3)
- megadl 'https://mega.nz/#!AR1HwIIA!U3p46tM9SFMhKzbSwJIEiugdJDQ5mUSOC3twZL6UYTM' --path data --no-progress # celeba_generator.xml
- megadl 'https://mega.nz/#!hAslCCaL!2vWXjiPq3EbuLZbOvEDOI0y9VorGn5enUm7UMNWGrWo' --path data --no-progress # celeba_generator.bin
- /opt/intel/openvino/deployment_tools/model_optimizer/mo.py --input_model data/frozen_unet_histology.pb --input_shape [1,952,1144,1,1,3] --output_dir data

script:
- source /opt/intel/openvino/bin/setupvars.sh -pyver 3.5
Expand Down
5 changes: 5 additions & 0 deletions modules/6_segmentation/include/segmentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class ADAS : public Segmenter {
ADAS();

virtual void segment(const cv::Mat& image, cv::Mat& mask);

private:
InferenceEngine::InferRequest req;
std::string outputName;
};

// Glands segmentation in colon histology images
Expand Down Expand Up @@ -53,4 +57,5 @@ class UNetHistology : public Segmenter {

private:
InferenceEngine::InferRequest req;
std::string outputName;
};
38 changes: 36 additions & 2 deletions modules/6_segmentation/src/segmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using namespace cv;
using namespace cv::utils::fs;

float Dice(const Mat& a, const Mat& b) {
CV_Error(Error::StsNotImplemented, "Dice score computation");
return (float)countNonZero(a&b) * 2.0f / (float)(countNonZero(a) + countNonZero(b));
}

ADAS::ADAS() {
Expand All @@ -16,8 +16,42 @@ ADAS::ADAS() {
// Load deep learning network into memory
auto net = ie.ReadNetwork(join(DATA_FOLDER, "semantic-segmentation-adas-0001.xml"),
join(DATA_FOLDER, "semantic-segmentation-adas-0001.bin"));

InputInfo::Ptr inputInfo = net.getInputsInfo()["data"];
inputInfo->getPreProcess().setResizeAlgorithm(ResizeAlgorithm::RESIZE_BILINEAR);
inputInfo->setLayout(Layout::NHWC);
inputInfo->setPrecision(Precision::U8);
outputName = net.getOutputsInfo().begin()->first;

// Initialize runnable object on CPU device
ExecutableNetwork execNet = ie.LoadNetwork(net, "CPU");

// Create a single processing thread
req = execNet.CreateInferRequest();
}
Blob::Ptr wrapMatToBlob2(const Mat& m) {
CV_Assert(m.depth() == CV_8U);
std::vector<size_t> dims = { 1, (size_t)m.channels(), (size_t)m.rows, (size_t)m.cols };
return make_shared_blob<uint8_t>(TensorDesc(Precision::U8, dims, Layout::NHWC),
m.data);
}



void ADAS::segment(const Mat& image, Mat& mask) {
CV_Error(Error::StsNotImplemented, "ADAS semantic segmentation");
Blob::Ptr input = wrapMatToBlob2(image);

req.SetBlob("data", input);

req.Infer();
int* output = req.GetBlob(outputName)->buffer();
int Height = 1024;
int Width = 2048;
Mat res = Mat::zeros(Height, Width, CV_8UC1);
for (int i = 0; i < Height; i++) {
for (int j = 0; j < Width; j++) {
res.at<unsigned char>(i, j) = output[i * Width + j];
}
}
resize(res, mask, image.size());
}
42 changes: 37 additions & 5 deletions modules/6_segmentation/src/unet_histology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,21 @@ UNetHistology::UNetHistology() {

// Create a single processing thread
req = execNet.CreateInferRequest();
outputName = net.getOutputsInfo().begin()->first;
}

void UNetHistology::bgr2rgb(const Mat& src, Mat& dst) {
CV_Error(Error::StsNotImplemented, "bgr2rgb");
cvtColor(src, dst, COLOR_BGR2RGB);
}


void UNetHistology::normalize(const Mat& src, Mat& dst) {
CV_Error(Error::StsNotImplemented, "normalize");
Scalar mean, std;
meanStdDev(src, mean, std);
dst = Mat::zeros(src.size(), CV_32FC3);
dst += src;
dst -= mean;
dst /= std;
}

void UNetHistology::segment(const Mat& image, Mat& mask) {
Expand Down Expand Up @@ -64,12 +70,38 @@ void UNetHistology::segment(const Mat& image, Mat& mask) {
Blob::Ptr inputBlob = wrapMatToBlob(inp);

// TODO: Put inputBlob to the network, perform inference and return mask

CV_Error(Error::StsNotImplemented, "UNetHistology semantic segmentation");
req.SetBlob("worker_0/validation/IteratorGetNext", inputBlob);

// Launch network
req.Infer();

// Copy output. "prob" is a name of output from .xml file
int* output = req.GetBlob(outputName)->buffer();
int Height = 772;
int Width = 964;
Mat res = Mat::zeros(Height, Width, CV_8UC1);
for (int i = 0; i < Height; i++) {
for (int j = 0; j < Width; j++) {
res.at<unsigned char>(i, j) = output[i * Width + j];
}
}
resize(res, mask, image.size());

}

int UNetHistology::countGlands(const cv::Mat& segm) {
CV_Error(Error::StsNotImplemented, "countGlands");
Mat thresh;
threshold(segm, thresh, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
morphologyEx(thresh, thresh, MORPH_CLOSE, Mat::ones(3, 3, CV_8U), Point(-1, -1), 3);
dilate(thresh, thresh, 3);
distanceTransform(thresh, thresh, DIST_L2, 5);
double maxValue;
minMaxLoc(thresh, 0 , &maxValue);
threshold(thresh, thresh, 0.45*maxValue, 255, 0);
thresh.convertTo(thresh, CV_8U);
std::vector<std::vector<Point> > contours;
findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
return contours.size();
}

void UNetHistology::padMinimum(const Mat& src, int width, int height, Mat& dst) {
Expand Down