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

[GSOC 2019] Global sampling matting #2134

Closed
wants to merge 71 commits into from
Closed

Conversation

Nerdyvedi
Copy link

@Nerdyvedi Nerdyvedi commented Jun 3, 2019

Merge with extra: opencv/opencv_extra#669
relates PR: #2198

This pullrequest is the C++ implementation of the Global sampling method for matting.

Global sampling method for matting by Matting Kaiming He1, Christoph Rhemann2, Carsten Rother3, Xiaoou Tang1,Jian Sun.

This blog post gives a summary of the paper:

Input to the model is the image and a trimap, and the output is the alpha matte of the image.

Steps

Use the following command to run the program

g++ pkg-config --cflags opencv globalmatting.cpp pkg-config --libs opencv -o matting

This produces an executable file called matting

To run the executable file, use the following command

./matting <Path to input image> <Path to trimap> <niter>(number of iterations for expansion of known regions[optional])

Results

After evaluating this implementation on alphamatting.com, the results are almost as good as the original implementation.

Following were the results:

Error type Original implementation This implementation
Sum of absolute differences 31 31.3
Mean square error 28.3 29.5
Gradient error 25 26.3
Connectivity error 28 36.3

Some of the outputs with of this implementation are as follows :

Image Trimap Alpha matte(this implementation)
alt text alt text alt text
alt text alt text alt text
alt text alt text alt text
force_builders=linux,Docs,Win64,Mac,Win32

@alalek
Copy link
Member

alalek commented Jun 3, 2019

  1. All modules names are lower-case. Almost all files should be lower case too.
  2. Avoid 'delete something' commits in patch. The same note for 'merge' commits. Your patch should be clean as much as possible.

@StevenPuttemans
Copy link

@alalek thanks for the basic pointers

@Nerdyvedi I will get through the PR at the end of the week and give you weekly feedback on the status so far. Make sure the commit history is clean and understandable. You can easily squash commits locally using the rebase tool in git, and then make a clean history by force pushing your changes.

Overall, as discussed, lets first focus on getting the complete AlphaGAN and Global Sampling method ready, since the other matting student is focussing on the information flow paper as main contribution. We rather have your other 2 papers as robust implementations, thouroughly tested and even possibly with Python bindings.

This build bot overview page gives you a clear overview of the issues that might arise with your current code. Once the tests have been completed, any errors will pop up there.

In general, feel free to update you starting message with any tests / graphs / progress bullets / ... so we can monitor easily what has been done so far.

Copy link

@StevenPuttemans StevenPuttemans left a comment

Choose a reason for hiding this comment

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

First review

Since you have these blog posts, which you referred to in chat, add them as extra explanation in the topic description of this pull request. It helps people understand what you are doing.

I will comment in between the code for specifics, but will ask you to pay attention to these global things.

  • As commented previous by @alalek there is still a lot of capitals, spaces and dashed lines in the filenames. Remove them completely. For example the path modules/Matting/AlphaGAN-Matting/AlphaGAN/alphaGAN_eval.py should be changed to modules/matting/alphagan/eval.py for example. You need clear and logical names and structures. And try to avoid to many submodules.
  • In general I am missing comments. Each function, even in python scripts should be well documented and steps taken explained, so that future people who will work on this understand what you did.
  • Comments made in one file should be imposed on all the others. I will not keep repeating myself in subsequent files and expect you to do this.
  • I understand you replaced torch by t for ease of use, but it reduces clarity. I would replace all t. instances by torch. instances so that it is very clear which parts come from torch package.
  • I do get that sometimes class names with a capital can create clarity, but is it always necessary. I try to avoid that as much as possible.
  • In general, remove all debugging and commented out pieces of code, unless they really have to be there. In that case, add a DEBUG condition switch at the top.
  • It seems that you have a lot of binary files. Data should go to opencv_extra as a separate pull request https://github.com/opencv/opencv_extra and be used as test data. @alalek is there any decent guideline on how people have to do this?
  • It seems that the code for the guided filter is already in OpenCV and multiple other parts is already in OpenCV and should thus not be in this PR, but properly addressed from the correct modules and thus the ximgproc module should be included there.

import torchvision.transforms as transforms
import numpy as np
import torch as t
from model.AlphaGAN import NetG

Choose a reason for hiding this comment

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

Make sure that your import and from statements are clearly grouped. Avoid switching them in between so that people have a one view oversight.

from visualize import Visualizer
import tqdm

os.environ["CUDA_VISIBLE_DEVICES"] = '2'

Choose a reason for hiding this comment

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

Hard coding a GPU capable device cannot be done in a library. You will have to provide the user the possibility to assign which GPU he wants to use.

transforms.ToPILImage()
])

MODEL_DIR = '/data1/zzl/model/alphaGAN/new_trainset/netG/netG_40.pth'

Choose a reason for hiding this comment

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

Same with hard coded paths, I prefer a python file that accepts input arguments and then on top of this file in comments you describe what the file does and what input it expects. This allows more versatile use of your code.

padding_result = np.pad(img, ((0, h_padding - h), (0, w_padding - w), (0, 0)), 'mean')

return Image.fromarray(padding_result), int(w_padding/320), int(h_padding/320)
elif len(img_size) == 2:

Choose a reason for hiding this comment

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

If you look at the two conditions, there is common code in retrieving w and h padding. You could make a coditional check on the shape first and then move this code outside the condition, only needing this check once.


def combination(img_list, h_clip, w_clip):

column =[]

Choose a reason for hiding this comment

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

extra space for clarity



class Visualizer():
"""

Choose a reason for hiding this comment

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

Remove all the chinese signs and overburden.
Also how are we sure that this code is not licensed?


#include <opencv2/opencv.hpp>

void expansionOfKnownRegions(cv::InputArray img, cv::InputOutputArray trimap, int niter = 9);

Choose a reason for hiding this comment

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

The number of iterations here, is this always fixed? Do we want to change this value?

Copy link
Author

Choose a reason for hiding this comment

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

This function was used in the paper Shared sampling for real time matting, and it is mentioned that the number of iterations must be around 10.

Choose a reason for hiding this comment

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

Then I do get we want to set a default value, for example 9, but we would really like to have a setter and getter to change that value when desired.

padding_result = np.pad(img, ((0, h_padding - h), (0, w_padding - w)), 'constant', constant_values=0)

return Image.fromarray(padding_result), int(w_padding/320), int(h_padding/320)
else:
Copy link
Contributor

Choose a reason for hiding this comment

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

This else isn't needed. And by the comment of @StevenPuttemans may be the whole branching can be eliminated? Am I right?

@StevenPuttemans
Copy link

@czgdp1807 since this PR is the main place for discussing the advancement of the GSoC 2019 project of @Nerdyvedi I suggest that we keep discussions on what is a good way of contributing to the forum (https://answers.opencv.org/questions/) or to the online chat system on SLACK (https://open-cv.slack.com/) or freenode webchat (https://webchat.freenode.net/ - #opencv).

This will allow me to keep working on contents here, and share thoughts on good ways to contribute somewhere else :)

@czgdp1807
Copy link
Contributor

Please accept my apologies. I was just sort of interested in the code so went through it. I will take care from now onwards. Thanks for providing the direct links to the social platforms of OpenCV.

@StevenPuttemans
Copy link

@Nerdyvedi give me a heads up here when you are finished with the above commits, so that I am sure to evaluate the final version :)

@Nerdyvedi
Copy link
Author

@Nerdyvedi give me a heads up here when you are finished with the above commits, so that I am sure to evaluate the final version :)

I am first trying to merge the implementation of Global sampling method for matting, as it's implementation is complete, and I don't think a lot of changes would be needed.

@StevenPuttemans
Copy link

Make sure you squash all commits in the end. Commit history should be clear.

Since you are splitting Global Sampling Method and AlphaGAN, in what seems to be seperate PRS, create both and change their name, so that they resemble the same. Now it may look that you did less than before.

Also by removing most of the AlphaGAN files, the comments are gone, so I hope you took time to note them down.

@StevenPuttemans
Copy link

@alalek 2 questions on technicalities

  1. The current warning of patch size > 5MB, is that something we can solve at our end?
  2. Where will we need to place all the data for the AlphaGAN? Like datasets that we created? Put it on opencv_extra also?

@StevenPuttemans
Copy link

and maybe a 3rd question. The stereo tests seem to fail, but they are unrelated to this code. Any idea why this happens? We need to wait for other PR to get merged?

@Nerdyvedi Nerdyvedi changed the title [GSOC 2019] Alpha Matting [GSOC 2019] Global sampling matting Jul 23, 2019
@StevenPuttemans
Copy link

@mshabunin or @vpisarev is there maybe one of you that could answer the above questions addressed to @alalek? He might be on holidays?

@mshabunin
Copy link
Contributor

@StevenPuttemans , commits need to be squashed, then patch size will become normal. Stereo test failure seem to be sporadic, don't worry about it.

Shouldn't it be transformed into sample application in ximgproc module? Or tutorial? Or algorithm + test + sample application?
Currently it does not get covered by CI at all.

@StevenPuttemans
Copy link

@mshabunin thanks for the feedback :) About your last comment. It is not ready yet, but you have a good point. The reason of building a matting module, has been that several students will work on this. On the other hand, we can put it also under the ximgproc module indeed.

Final idea is indeed algorithm + test + sample for usage + tutorial.

@Nerdyvedi Nerdyvedi force-pushed the master branch 2 times, most recently from 908b1bc to 5aa25e9 Compare July 31, 2019 21:58
@StevenPuttemans
Copy link

@Nerdyvedi can you please provide an update on your progress? This PR must contain your final code before end of GSoC for the global sampling part of the project.

public:
GlobalMatting();

void globalMatting(cv::InputArray _image, cv::InputArray _trimap, cv::OutputArray _foreground, cv::OutputArray _alpha, cv::OutputArray _conf);
Copy link
Member

Choose a reason for hiding this comment

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

Please avoid using of 'tabs'. Indentation is 4 spaces (no need to indent after opening of "whole-file" namespaces)

#ifndef GLOBAL_MATTING_H
#define GLOBAL_MATTING_H

#include <opencv2/highgui.hpp>
Copy link
Member

Choose a reason for hiding this comment

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

Please remove highgui from public header and from module dependency.


#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/ximgproc/edge_filter.hpp>
Copy link
Member

Choose a reason for hiding this comment

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

Include headers which are required to describe this public API only. Remove other.

if(img.empty() || trimap.empty())
{
ts->printf(cvtest::TS::LOG,"Test images not found!\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
Copy link
Member

Choose a reason for hiding this comment

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

ASSERT_FALSE(img.empty() || trimap.empty()) << "Test images not found!";



class CV_GlobalMattingTest : public cvtest::BaseTest
{
Copy link
Member

Choose a reason for hiding this comment

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

This class is not needed (BaseTest is a legacy stuff).
Put all test code into TEST() body.

Copy link
Author

Choose a reason for hiding this comment

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

Should I use TEST instead of BaseTest, sorry sir, I didn't quite get it.

Copy link
Member

Choose a reason for hiding this comment

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

You should not use cvtest::BaseTest (it is legacy).

TEST() and other GoogleTest stuff is enough.

void CV_GlobalMattingTest::runModel()
{
std::string img_path = std::string(ts->get_data_path()) + INPUT_DIR + "/" + IMAGE_FILENAME;
std::string trimap_path = std::string(ts->get_data_path()) + INPUT_DIR + "/" + TRIMAP_FILENAME;
Copy link
Member

Choose a reason for hiding this comment

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

ts->get_data_path()

Use cvtest::findDataFile(INPUT_DIR + "/" + IMAGE_FILENAME)

Copy link
Author

Choose a reason for hiding this comment

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

@alalek , Could you please take a look , the buildbots tests are not queued.

modules/ximgproc/src/globalmatting.cpp Outdated Show resolved Hide resolved
@alalek
Copy link
Member

alalek commented Aug 30, 2019

@Nerdyvedi Please add missing files here from #2198 (keep changes in a single PR)

@StevenPuttemans
Copy link

@alalek @mshabunin is there anyone that knows why this pullrequest is not qeued for buildbots? @Nerdyvedi would like to make sure it gets all green flags so that it can get integrated into the library.

@alalek
Copy link
Member

alalek commented Sep 25, 2019

Because of "master" source branch: from Nerdyvedi:master.

Build process of OpenCV uses multiple repositories, so it can't be handled automatically by CI.
We prefer using of properly named source branches: https://github.com/opencv/opencv/wiki/How_to_contribute#the-instruction-in-brief (item 6)
All forks have "master" branch (usually stalled), but only useful branches has proper names.

@StevenPuttemans
Copy link

Ow okay! We will fix that!

@alalek
Copy link
Member

alalek commented Sep 25, 2019

Unfortunately this can't be fixed without PR re-creation due GitHub limitations.
It is better to continue here (to avoid lost of review progress).

@Nerdyvedi Nerdyvedi closed this Sep 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants