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

Remove dependences of cv2 #27286

Merged
merged 7 commits into from
Sep 18, 2020
Merged
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
1 change: 1 addition & 0 deletions python/paddle/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .profiler import Profiler
from .profiler import get_profiler
from .deprecated import deprecated
from .lazy_import import try_import
from ..fluid.framework import unique_name
from ..fluid.framework import load_op_library
from ..fluid.framework import require_version
Expand Down
34 changes: 34 additions & 0 deletions python/paddle/utils/lazy_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Lazy imports for heavy dependencies."""

import importlib


def try_import(module_name):
"""Try importing a module, with an informative error message on failure."""
install_name = module_name
if module_name == 'cv2':
install_name = 'opencv-python'

try:
mod = importlib.import_module(module_name)
return mod
except ImportError:
err_msg = (
"Failed importing {}. This likely means that some paddle modules "
"requires additional dependencies that have to be "
"manually installed (usually with `pip install {}`). ").format(
module_name, install_name)
raise ImportError(err_msg)
3 changes: 2 additions & 1 deletion python/paddle/vision/datasets/folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

import os
import sys
import cv2

from paddle.io import Dataset
from paddle.utils import try_import

__all__ = ["DatasetFolder", "ImageFolder"]

Expand Down Expand Up @@ -191,6 +191,7 @@ def __len__(self):


def cv2_loader(path):
cv2 = try_import('cv2')
return cv2.imread(path)


Expand Down
51 changes: 35 additions & 16 deletions python/paddle/vision/transforms/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
import math
import functools

import cv2
import numbers
import numpy as np

from paddle.utils import try_import

if sys.version_info < (3, 3):
Sequence = collections.Sequence
Iterable = collections.Iterable
Expand Down Expand Up @@ -54,8 +55,8 @@ def flip(image, code):
Accordding to the code (the type of flip), flip the input image

Args:
image: Input image, with (H, W, C) shape
code: Code that indicates the type of flip.
image (np.ndarray): Input image, with (H, W, C) shape
code (int): Code that indicates the type of flip.
-1 : Flip horizontally and vertically
0 : Flip vertically
1 : Flip horizontally
Expand All @@ -77,18 +78,28 @@ def flip(image, code):
# flip horizontally
F.flip(fake_img, 1)
"""
cv2 = try_import('cv2')
return cv2.flip(image, flipCode=code)


@keepdims
def resize(img, size, interpolation=cv2.INTER_LINEAR):
def resize(img, size, interpolation=1):
"""
resize the input data to given size

Args:
input: Input data, could be image or masks, with (H, W, C) shape
size: Target size of input data, with (height, width) shape.
interpolation: Interpolation method.
input (np.ndarray): Input data, could be image or masks, with (H, W, C) shape
size (int|list|tuple): Target size of input data, with (height, width) shape.
interpolation (int, optional): Interpolation method.
0 : cv2.INTER_NEAREST
1 : cv2.INTER_LINEAR
2 : cv2.INTER_CUBIC
3 : cv2.INTER_AREA
4 : cv2.INTER_LANCZOS4
5 : cv2.INTER_LINEAR_EXACT
7 : cv2.INTER_MAX
8 : cv2.WARP_FILL_OUTLIERS
16: cv2.WARP_INVERSE_MAP

Examples:
.. code-block:: python
Expand All @@ -102,7 +113,7 @@ def resize(img, size, interpolation=cv2.INTER_LINEAR):

F.resize(fake_img, (200, 150))
"""

cv2 = try_import('cv2')
if isinstance(interpolation, Sequence):
interpolation = random.choice(interpolation)

Expand Down Expand Up @@ -179,6 +190,8 @@ def pad(img, padding, fill=(0, 0, 0), padding_mode='constant'):
assert padding_mode in ['constant', 'edge', 'reflect', 'symmetric'], \
'Expected padding mode be either constant, edge, reflect or symmetric, but got {}'.format(padding_mode)

cv2 = try_import('cv2')

PAD_MOD = {
'constant': cv2.BORDER_CONSTANT,
'edge': cv2.BORDER_REPLICATE,
Expand Down Expand Up @@ -214,18 +227,22 @@ def pad(img, padding, fill=(0, 0, 0), padding_mode='constant'):


@keepdims
def rotate(img,
angle,
interpolation=cv2.INTER_LINEAR,
expand=False,
center=None):
def rotate(img, angle, interpolation=1, expand=False, center=None):
"""Rotates the image by angle.

Args:
img (numpy.ndarray): Image to be rotated.
angle (float|int): In degrees clockwise order.
interpolation (int, optional):
interpolation: Interpolation method.
interpolation (int, optional): Interpolation method. Default: 1.
0 : cv2.INTER_NEAREST
1 : cv2.INTER_LINEAR
2 : cv2.INTER_CUBIC
3 : cv2.INTER_AREA
4 : cv2.INTER_LANCZOS4
5 : cv2.INTER_LINEAR_EXACT
7 : cv2.INTER_MAX
8 : cv2.WARP_FILL_OUTLIERS
16: cv2.WARP_INVERSE_MAP
expand (bool|optional): Optional expansion flag.
If true, expands the output image to make it large enough to hold the entire rotated image.
If false or omitted, make the output image the same size as the input image.
Expand All @@ -250,8 +267,9 @@ def rotate(img,
fake_img = rotate(fake_img, 10)
print(fake_img.shape)
"""
dtype = img.dtype
cv2 = try_import('cv2')

dtype = img.dtype
h, w, _ = img.shape
point = center or (w / 2, h / 2)
M = cv2.getRotationMatrix2D(point, angle=-angle, scale=1)
Expand Down Expand Up @@ -312,6 +330,7 @@ def to_grayscale(img, num_output_channels=1):
fake_img = to_grayscale(fake_img)
print(fake_img.shape)
"""
cv2 = try_import('cv2')

if num_output_channels == 1:
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
Expand Down
61 changes: 49 additions & 12 deletions python/paddle/vision/transforms/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import math
import sys
import random
import cv2

import numpy as np
import numbers
Expand All @@ -26,6 +25,7 @@
import warnings
import traceback

from paddle.utils import try_import
from . import functional as F

if sys.version_info < (3, 3):
Expand Down Expand Up @@ -214,7 +214,16 @@ class Resize(object):
smaller edge of the image will be matched to this number.
i.e, if height > width, then image will be rescaled to
(size * height / width, size)
interpolation (int): Interpolation mode of resize. Default: cv2.INTER_LINEAR.
interpolation (int, optional): Interpolation mode of resize. Default: 1.
0 : cv2.INTER_NEAREST
1 : cv2.INTER_LINEAR
2 : cv2.INTER_CUBIC
3 : cv2.INTER_AREA
4 : cv2.INTER_LANCZOS4
5 : cv2.INTER_LINEAR_EXACT
7 : cv2.INTER_MAX
8 : cv2.WARP_FILL_OUTLIERS
16: cv2.WARP_INVERSE_MAP

Examples:

Expand All @@ -232,7 +241,7 @@ class Resize(object):
print(fake_img.shape)
"""

def __init__(self, size, interpolation=cv2.INTER_LINEAR):
def __init__(self, size, interpolation=1):
assert isinstance(size, int) or (isinstance(size, Iterable) and
len(size) == 2)
self.size = size
Expand All @@ -252,6 +261,16 @@ class RandomResizedCrop(object):
output_size (int|list|tuple): Target size of output image, with (height, width) shape.
scale (list|tuple): Range of size of the origin size cropped. Default: (0.08, 1.0)
ratio (list|tuple): Range of aspect ratio of the origin aspect ratio cropped. Default: (0.75, 1.33)
interpolation (int, optional): Interpolation mode of resize. Default: 1.
0 : cv2.INTER_NEAREST
1 : cv2.INTER_LINEAR
2 : cv2.INTER_CUBIC
3 : cv2.INTER_AREA
4 : cv2.INTER_LANCZOS4
5 : cv2.INTER_LINEAR_EXACT
7 : cv2.INTER_MAX
8 : cv2.WARP_FILL_OUTLIERS
16: cv2.WARP_INVERSE_MAP

Examples:

Expand All @@ -273,7 +292,7 @@ def __init__(self,
output_size,
scale=(0.08, 1.0),
ratio=(3. / 4, 4. / 3),
interpolation=cv2.INTER_LINEAR):
interpolation=1):
if isinstance(output_size, int):
self.output_size = (output_size, output_size)
else:
Expand Down Expand Up @@ -328,7 +347,16 @@ class CenterCropResize(object):
Args:
size (int|list|tuple): Target size of output image, with (height, width) shape.
crop_padding (int): Center crop with the padding. Default: 32.
interpolation (int): Interpolation mode of resize. Default: cv2.INTER_LINEAR.
interpolation (int, optional): Interpolation mode of resize. Default: 1.
0 : cv2.INTER_NEAREST
1 : cv2.INTER_LINEAR
2 : cv2.INTER_CUBIC
3 : cv2.INTER_AREA
4 : cv2.INTER_LANCZOS4
5 : cv2.INTER_LINEAR_EXACT
7 : cv2.INTER_MAX
8 : cv2.WARP_FILL_OUTLIERS
16: cv2.WARP_INVERSE_MAP

Examples:

Expand All @@ -346,7 +374,7 @@ class CenterCropResize(object):
print(fake_img.shape)
"""

def __init__(self, size, crop_padding=32, interpolation=cv2.INTER_LINEAR):
def __init__(self, size, crop_padding=32, interpolation=1):
if isinstance(size, int):
self.size = (size, size)
else:
Expand Down Expand Up @@ -661,6 +689,7 @@ def __call__(self, img):
if self.value == 0:
return img

cv2 = try_import('cv2')
dtype = img.dtype
img = img.astype(np.float32)
alpha = np.random.uniform(max(0, 1 - self.value), 1 + self.value)
Expand Down Expand Up @@ -701,6 +730,8 @@ def __call__(self, img):
if self.value == 0:
return img

cv2 = try_import('cv2')

dtype = img.dtype
img = img.astype(np.float32)
alpha = np.random.uniform(max(0, 1 - self.value), 1 + self.value)
Expand Down Expand Up @@ -742,6 +773,7 @@ def __call__(self, img):
if self.value == 0:
return img

cv2 = try_import('cv2')
dtype = img.dtype
img = img.astype(np.uint8)
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
Expand Down Expand Up @@ -1036,7 +1068,16 @@ class RandomRotate(object):
degrees (sequence or float or int): Range of degrees to select from.
If degrees is a number instead of sequence like (min, max), the range of degrees
will be (-degrees, +degrees) clockwise order.
interpolation (int|optional): Interpolation mode of resize. Default: cv2.INTER_LINEAR.
interpolation (int, optional): Interpolation mode of resize. Default: 1.
0 : cv2.INTER_NEAREST
1 : cv2.INTER_LINEAR
2 : cv2.INTER_CUBIC
3 : cv2.INTER_AREA
4 : cv2.INTER_LANCZOS4
5 : cv2.INTER_LINEAR_EXACT
7 : cv2.INTER_MAX
8 : cv2.WARP_FILL_OUTLIERS
16: cv2.WARP_INVERSE_MAP
expand (bool|optional): Optional expansion flag. Default: False.
If true, expands the output to make it large enough to hold the entire rotated image.
If false or omitted, make the output image the same size as the input image.
Expand All @@ -1061,11 +1102,7 @@ class RandomRotate(object):
print(fake_img.shape)
"""

def __init__(self,
degrees,
interpolation=cv2.INTER_LINEAR,
expand=False,
center=None):
def __init__(self, degrees, interpolation=1, expand=False, center=None):
if isinstance(degrees, numbers.Number):
if degrees < 0:
raise ValueError(
Expand Down
1 change: 0 additions & 1 deletion python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
opencv-python<=4.2.0.32
requests>=2.20.0
Copy link
Contributor

Choose a reason for hiding this comment

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

requirements中去掉后,CI的脚本里应该需要加下 https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/scripts/paddle_build.sh

Copy link
Contributor Author

Choose a reason for hiding this comment

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

感谢,这个田硕老师帮忙解决了:#27378

numpy>=1.13, <=1.16.4 ; python_version<"3.5"
numpy>=1.13 ; python_version>="3.5"
Expand Down
3 changes: 0 additions & 3 deletions python/setup.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,6 @@ if sys.version_info >= (3,7):
setup_requires_tmp+=[setup_requires_i]
setup_requires = setup_requires_tmp

if '${CMAKE_SYSTEM_PROCESSOR}' not in ['arm', 'armv7-a', 'aarch64']:
setup_requires+=['opencv-python']

# the prefix is sys.prefix which should always be usr
paddle_bins = ''

Expand Down