Extracting Car Outlines from Sample Images for 360° Vehicle Capture in an iOS App
This article describes a step‑by‑step iOS implementation that converts example car images into bitmap points, scans edges, removes duplicate points, compensates missing vertices, and finally builds a closed BezierPath to guide 360° vehicle photography, including full Objective‑C code snippets.
Background – Users typically view cars online in a uniform way, so the team needed a method to let merchants capture 360° vehicle images at home. Simple example‑image guidance proved unreliable due to varying shooting distances and angles, prompting the development of an automated contour‑extraction and shooting‑assist component for the CarSmart+ app.
Implementation Idea – The process starts by converting the example image to bitmap points, then scanning from top, bottom, left, and right according to a known rule (non‑transparent pixels) to obtain four edge point arrays. These arrays are merged into an ordered set of points, which are then connected to form a closed BezierPath.
Problems Encountered – Directly merging the four edge arrays caused duplicate points and non‑continuous sequences, resulting in malformed shapes. The solution was to de‑duplicate the horizontal (left/right) and vertical (top/bottom) arrays separately, then use the vertical arrays to supplement the horizontal ones before final merging.
Final Implementation and Core Code
NSMutableArray<NSValue *> *arrLeft = [NSMutableArray array];
NSMutableArray<NSValue *> *arrBottom = [NSMutableArray array];
NSMutableArray<NSValue *> *arrRight = [NSMutableArray array];
NSMutableArray<NSValue *> *arrTop = [NSMutableArray array];
for (NSInteger row = 0; row < h; row++) {
// left edge
for (NSInteger col = 0; col < w; col++) {
const uint8_t *pixel = &rgba[row * bytesPerRow + col * bytesPerPixel];
if (pixel[3] != 0x00) { [arrLeft addObject:[NSValue valueWithCGPoint:CGPointMake(col, row)]]; break; }
}
// right edge
for (NSInteger col = w - 1; col >= 0; col--) {
const uint8_t *pixel = &rgba[row * bytesPerRow + col * bytesPerPixel];
if (pixel[3] != 0x00) { [arrRight insertObject:[NSValue valueWithCGPoint:CGPointMake(col, row)] atIndex:0]; break; }
}
}
for (NSInteger col = 0; col < w; col++) {
// bottom edge
for (NSInteger row = h - 1; row >= 0; row--) {
const uint8_t *pixel = &rgba[row * bytesPerRow + col * bytesPerPixel];
if (pixel[3] != 0x00) { [arrBottom addObject:[NSValue valueWithCGPoint:CGPointMake(col, row)]]; break; }
}
// top edge
for (NSInteger row = 0; row < h; row++) {
const uint8_t *pixel = &rgba[row * bytesPerRow + col * bytesPerPixel];
if (pixel[3] != 0x00) { [arrTop insertObject:[NSValue valueWithCGPoint:CGPointMake(col, row)] atIndex:0]; break; }
}
} NSMutableSet *arrLeftSet = [NSMutableSet setWithArray:arrLeft];
NSMutableSet *arrRightSet = [NSMutableSet setWithArray:arrRight];
NSMutableSet *arrBottomSet = [NSMutableSet setWithArray:arrBottom];
NSMutableSet *arrTopSet = [NSMutableSet setWithArray:arrTop];
[arrLeftSet intersectSet:arrRightSet];
for (int i = (int)(arrRight.count - 1); i >= 0; i--) {
@autoreleasepool { NSValue *value = arrRight[i]; if ([arrLeftSet containsObject:value]) [arrRight removeObject:value]; }
}
[arrBottomSet intersectSet:arrTopSet];
for (int i = (int)(arrTop.count - 1); i >= 0; i--) {
@autoreleasepool { NSValue *value = arrTop[i]; if ([arrBottomSet containsObject:value]) [arrTop removeObject:value]; }
} // arrFixPoints is the top or bottom edge array
NSMutableSet<NSValue *> *arrCoincidentPointsSet = [NSMutableSet setWithArray:arrFixPoints];
// arrOriginalPoints is the left or right edge array
[arrCoincidentPointsSet intersectSet:[NSSet setWithArray:arrOriginalPoints]];Effect Demonstration – The resulting BezierPath accurately outlines the vehicle, as shown in the before‑and‑after screenshots, improving both shooting efficiency and quality for merchants.
Conclusion – While many contour‑extraction methods exist (OpenCV, Vision, DeepLab), the specific constraints of the sample images allowed a lightweight, rule‑based solution without external libraries. Future work may explore more robust or AI‑driven approaches.
HomeTech
HomeTech tech sharing
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.