haruntrkmn commited on
Commit
5c7578b
·
verified ·
1 Parent(s): 464efe3

Upload 2 files

Browse files
Files changed (2) hide show
  1. README.md +122 -0
  2. utils.py +148 -0
README.md ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ pipeline_tag: image-segmentation
4
+ language: []
5
+ base_model: isnet-general-use.pth
6
+ model_type: ty_fashion_bg_remover
7
+ tags:
8
+ - computer-vision
9
+ - image-background-removal
10
+ - image-matting
11
+ - e-commerce
12
+ - is-net
13
+ ---
14
+
15
+ # TY Fashion Background Remover
16
+
17
+ _IS-Net-based fashion image background removal model for removing background of fashion images on the Trendyol e-commerce catalogue._
18
+
19
+ ## Model Details
20
+
21
+ - **Architecture**: IS-Net
22
+ - **Objective**: Fine-tuning isnet-general-use model with TY fashion images to better performance of fashion images
23
+ - **Training Data**: Large-scale Trendyol fashion product image dataset containing human models
24
+ - **Hardware**: Multi-GPU training with PyTorch
25
+ - **Framework**: PyTorch
26
+
27
+ ## Intended Use
28
+
29
+ - Isolate human models in fashion product images by removing the image background
30
+
31
+ ## Usage
32
+
33
+ Complete example to load the model, remove background of an image, and save the results:
34
+
35
+ ```python
36
+ """
37
+ ONNX inference script for image segmentation model.
38
+
39
+ This script loads an ONNX model and performs inference on an input image to generate
40
+ an alpha mask. The mask is combined with the RGB image and saved as output.
41
+ """
42
+
43
+ import onnxruntime as ort
44
+ from utils import process_image
45
+
46
+ if __name__ == "__main__":
47
+ MODEL_PATH = "model.onnx"
48
+ SRC = "https://cdn.dsmcdn.com/ty184/product/media/images/20210924/23/136268224/224296134/1/1_org_zoom.jpg"
49
+ OUTPUT_FILE = "out.png"
50
+
51
+ # Initialize ONNX runtime session with CUDA and CPU providers
52
+ ort_session = ort.InferenceSession(
53
+ MODEL_PATH,
54
+ providers=["CUDAExecutionProvider", "CPUExecutionProvider"]
55
+ )
56
+
57
+ process_image(SRC, ort_session, MODEL_PATH, OUTPUT_FILE)
58
+ ```
59
+
60
+ ## Model Performance
61
+
62
+ - **Achieve high-accuracy image matting**: Especially for intricate details on human models, such as hair and clothing textures.
63
+
64
+ ### Training Configuration
65
+
66
+ - **Backbone**: IS-Net general use model trained on DIS dataset V1.0: DIS5K
67
+ - **Model Input Size**: 1800x1200
68
+ - **Training Framework**: Torch 1.13.1
69
+
70
+ ## Limitations
71
+
72
+ - **Domain Specificity**: Optimized for e-commerce fashion product images with human models included; may not generalize well to other image domains
73
+ - **Image Quality**: Performance may degrade on low-quality, heavily compressed, or significantly distorted images
74
+ - **Category Bias**: Performance may vary across different product categories based on training data distribution
75
+
76
+ ## Ethical Considerations
77
+
78
+ - **Commercial Use**: Designed for e-commerce applications; consider potential impacts on market competition
79
+ - **Privacy**: Ensure compliance with data protection regulations when processing product images
80
+ - **Fairness**: Monitor for biased similarity judgments across different product categories or brands
81
+
82
+ ## Citation
83
+
84
+ ```bibtex
85
+ @misc{trendyol2025fashionbgremover,
86
+ title={TY Fashion Background Remover},
87
+ author={Trendyol Data Science Team},
88
+ year={2025},
89
+ howpublished={\url{https://huggingface.co/trendyol/ty-fashion-bg-remover}}
90
+ }
91
+ ```
92
+
93
+ ## Model Card Authors
94
+
95
+ - Trendyol Data Science Team
96
+
97
+ ## License
98
+
99
+ This model is released by Trendyol as a source-available, non-open-source model.
100
+
101
+ ### You are allowed to:
102
+
103
+ - View, download, and evaluate the model weights.
104
+ - Use the model for non-commercial research and internal testing.
105
+ - Use the model or its derivatives for commercial purposes, provided that:
106
+ - You cite Trendyol as the original model creator.
107
+ - You notify Trendyol in advance via [[email protected]] or other designated contact.
108
+
109
+ ### You are not allowed to:
110
+
111
+ - Redistribute or host the model or its derivatives on third-party platforms without prior written consent from Trendyol.
112
+ - Use the model in applications violating ethical standards, including but not limited to surveillance, misinformation, or harm to individuals or groups.
113
+
114
+ By downloading or using this model, you agree to the terms above.
115
+
116
+ © 2025 Trendyol Teknoloji A.Ş. All rights reserved.
117
+
118
+ See the [LICENSE](LICENSE) file for more details.
119
+
120
+ ---
121
+
122
+ _For technical support or questions about this model, please contact the Trendyol Data Science team._
utils.py ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import requests
4
+ from PIL import Image
5
+ from io import BytesIO
6
+ import torch
7
+ from pathlib import Path
8
+ import torch.nn.functional as F
9
+ from typing import Dict, Any, List, Union, Tuple
10
+ from torchvision.transforms.functional import normalize
11
+
12
+ INPUT_SIZE = [1200, 1800]
13
+
14
+ def keep_large_components(a: np.ndarray) -> np.ndarray:
15
+ """Remove small connected components from a binary mask, keeping only large regions.
16
+
17
+ Args:
18
+ a: Input binary mask as numpy array of shape (H,W) or (H,W,1)
19
+
20
+ Returns:
21
+ Processed mask with only large connected components remaining, shape (H,W,1)
22
+ """
23
+ dilate_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(9, 9))
24
+ a_mask = (a > 25).astype(np.uint8) * 255
25
+
26
+ # Apply the Component analysis function
27
+ analysis = cv2.connectedComponentsWithStats(a_mask, 4, cv2.CV_32S)
28
+ (totalLabels, label_ids, values, centroid) = analysis
29
+
30
+ # Find the components to be kept
31
+ h, w = a.shape[:2]
32
+ area_limit = 50000 * (h * w) / (INPUT_SIZE[1] * INPUT_SIZE[0])
33
+ i_to_keep = []
34
+ for i in range(1, totalLabels):
35
+ area = values[i, cv2.CC_STAT_AREA]
36
+ if area > area_limit:
37
+ i_to_keep.append(i)
38
+
39
+ if len(i_to_keep) > 0:
40
+ # Or masks to be kept
41
+ final_mask = np.zeros_like(a, dtype=np.uint8)
42
+ for i in i_to_keep:
43
+ componentMask = (label_ids == i).astype("uint8") * 255
44
+ final_mask = cv2.bitwise_or(final_mask, componentMask)
45
+
46
+ # Remove other components
47
+ # Keep edges
48
+ final_mask = cv2.dilate(final_mask, dilate_kernel, iterations = 2)
49
+ a = cv2.bitwise_and(a, final_mask)
50
+ a = a.reshape((a.shape[0], a.shape[1], 1))
51
+
52
+ return a
53
+
54
+ def read_img(img: Union[str, Path]) -> np.ndarray:
55
+ """Read an image from a URL or local path.
56
+
57
+ Args:
58
+ img: URL or file path to image
59
+
60
+ Returns:
61
+ Image as numpy array in RGB format with shape (H,W,3)
62
+ """
63
+ if img[0: 4] == 'http':
64
+ response = requests.get(img)
65
+ im = np.asarray(Image.open(BytesIO(response.content)))
66
+
67
+ else:
68
+ im = cv2.imread(str(img))
69
+ im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
70
+
71
+ return im
72
+
73
+ def preprocess_input(im: np.ndarray) -> torch.Tensor:
74
+ """Preprocess image for model input.
75
+
76
+ Args:
77
+ im: Input image as numpy array of shape (H,W,C)
78
+
79
+ Returns:
80
+ Preprocessed image as normalized torch tensor of shape (1,3,H,W)
81
+ """
82
+ if len(im.shape) < 3:
83
+ im = im[:, :, np.newaxis]
84
+
85
+ if im.shape[2] == 4: # if image has alpha channel, remove it
86
+ im = im[:,:,:3]
87
+
88
+ im_tensor = torch.tensor(im, dtype=torch.float32).permute(2,0,1)
89
+ im_tensor = F.upsample(torch.unsqueeze(im_tensor,0), INPUT_SIZE, mode="bilinear").type(torch.uint8)
90
+ image = torch.divide(im_tensor,255.0)
91
+ image = normalize(image,[0.5,0.5,0.5],[1.0,1.0,1.0])
92
+
93
+ if torch.cuda.is_available():
94
+ image=image.cuda()
95
+
96
+ return image
97
+
98
+ def postprocess_output(result: np.ndarray, orig_im_shape: Tuple[int, int]) -> np.ndarray:
99
+ """Postprocess ONNX model output.
100
+
101
+ Args:
102
+ result: Model output as numpy array of shape (1,1,H,W)
103
+ orig_im_shape: Original image dimensions (height, width)
104
+
105
+ Returns:
106
+ Processed binary mask as numpy array of shape (H,W,1)
107
+ """
108
+ result = torch.squeeze(F.upsample(
109
+ torch.from_numpy(result).unsqueeze(0), (orig_im_shape), mode='bilinear'), 0)
110
+ ma = torch.max(result)
111
+ mi = torch.min(result)
112
+ result = (result-mi)/(ma-mi)
113
+
114
+ # a is alpha channel. 255 means foreground, 0 means background.
115
+ a = (result*255).permute(1,2,0).cpu().data.numpy().astype(np.uint8)
116
+
117
+ # postprocessing
118
+ a = keep_large_components(a)
119
+
120
+ return a
121
+
122
+ def process_image(src: Union[str, Path], ort_session: Any, model_path: Union[str, Path], outname: str) -> None:
123
+ """Process an image through ONNX model to generate alpha mask and save result.
124
+
125
+ Args:
126
+ src: Source image URL or path
127
+ ort_session: ONNX runtime inference session
128
+ model_path: Path to ONNX model file
129
+ outname: Output filename for saving result
130
+
131
+ Returns:
132
+ None
133
+ """
134
+ # Load and preprocess image
135
+ image_orig = read_img(src)
136
+ image = preprocess_input(image_orig)
137
+
138
+ # Prepare ONNX input
139
+ inputs: Dict[str, Any] = {ort_session.get_inputs()[0].name: image.numpy()}
140
+
141
+ # Get ONNX output and post-process
142
+ result = ort_session.run(None, inputs)[0][0]
143
+ alpha = postprocess_output(result, (image_orig.shape[0], image_orig.shape[1]))
144
+
145
+ # Combine RGB image with alpha mask and save
146
+ img_w_alpha = np.dstack((cv2.cvtColor(image_orig, cv2.COLOR_BGR2RGB), alpha))
147
+ cv2.imwrite(outname, img_w_alpha)
148
+ print(f"Saved: {outname}")