Skip to content

Commit bdb5cbf

Browse files
authored
Fix vision samples (GoogleCloudPlatform#300)
* adds images * changes API key to project id * adds doc region tags for face and label detection * adds "output" for writing a bounding box in face detection
1 parent d3c3c8e commit bdb5cbf

File tree

8 files changed

+152
-54
lines changed

8 files changed

+152
-54
lines changed

vision/api/images/cat.jpg

72.8 KB
Loading

vision/api/images/eiffel_tower.jpg

162 KB
Loading

vision/api/images/face.png

458 KB
Loading

vision/api/src/DetectFaceCommand.php

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@
2929
*/
3030
class DetectFaceCommand extends Command
3131
{
32+
private $imageCreateFunc = [
33+
'png' => 'imagecreatefrompng',
34+
'gd' => 'imagecreatefromgd',
35+
'gif' => 'imagecreatefromgif',
36+
'jpg' => 'imagecreatefromjpeg',
37+
'jpeg' => 'imagecreatefromjpeg',
38+
];
39+
40+
private $imageWriteFunc = [
41+
'png' => 'imagepng',
42+
'gd' => 'imagegd',
43+
'gif' => 'imagegif',
44+
'jpg' => 'imagejpeg',
45+
'jpeg' => 'imagejpeg',
46+
];
47+
3248
protected function configure()
3349
{
3450
$this
@@ -48,19 +64,49 @@ protected function configure()
4864
InputArgument::REQUIRED,
4965
'The image to examine.'
5066
)
67+
->addArgument(
68+
'output',
69+
InputArgument::OPTIONAL,
70+
'The output image with bounding boxes.'
71+
)
5172
->addOption(
52-
'api-key',
53-
'k',
73+
'project',
74+
'p',
5475
InputOption::VALUE_REQUIRED,
55-
'Your API key.'
76+
'Your Project ID.'
5677
)
5778
;
5879
}
5980

6081
protected function execute(InputInterface $input, OutputInterface $output)
6182
{
62-
$apiKey = $input->getOption('api-key');
83+
$projectId = $input->getOption('project');
6384
$path = $input->getArgument('path');
64-
require(__DIR__ . '/snippets/detect_face.php');
85+
$result = require __DIR__ . '/snippets/detect_face.php';
86+
if (
87+
isset($result->info()['faceAnnotations'])
88+
&& $outFile = $input->getArgument('output')
89+
) {
90+
copy($path, $outFile);
91+
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
92+
if (!in_array($ext, array_keys($this->imageCreateFunc))) {
93+
throw new \Exception('Unsupported image extension');
94+
}
95+
$outputImage = call_user_func($this->imageCreateFunc[$ext], $outFile);
96+
# [START highlight_image]
97+
foreach ($result->info()['faceAnnotations'] as $annotation) {
98+
if (isset($annotation['boundingPoly'])) {
99+
$verticies = $annotation['boundingPoly']['vertices'];
100+
$x1 = isset($verticies[0]['x']) ? $verticies[0]['x'] : 0;
101+
$y1 = isset($verticies[0]['y']) ? $verticies[0]['y'] : 0;
102+
$x2 = isset($verticies[2]['x']) ? $verticies[2]['x'] : 0;
103+
$y2 = isset($verticies[2]['y']) ? $verticies[2]['y'] : 0;
104+
imagerectangle($outputImage, $x1, $y1, $x2, $y2, 0x00ff00);
105+
}
106+
}
107+
# [END highlight_image]
108+
call_user_func($this->imageWriteFunc[$ext], $outputImage, $outFile);
109+
printf('Output image written to %s' . PHP_EOL, $outFile);
110+
}
65111
}
66112
}

vision/api/src/DetectLabelCommand.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
* limitations under the License.
1616
*/
1717

18-
1918
namespace Google\Cloud\Samples\Vision;
2019

2120
use Symfony\Component\Console\Command\Command;
@@ -49,16 +48,16 @@ protected function configure()
4948
'The image to examine.'
5049
)
5150
->addOption(
52-
'api-key',
53-
'k',
51+
'project',
52+
'p',
5453
InputOption::VALUE_REQUIRED,
55-
'Your API key.'
54+
'Your Project ID.'
5655
);
5756
}
5857

5958
protected function execute(InputInterface $input, OutputInterface $output)
6059
{
61-
$apiKey = $input->getOption('api-key');
60+
$projectId = $input->getOption('project');
6261
$path = $input->getArgument('path');
6362
require(__DIR__ . '/snippets/detect_label.php');
6463
}

vision/api/src/snippets/detect_face.php

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,55 +18,59 @@
1818

1919
namespace Google\Cloud\Samples\Vision;
2020

21-
// [START face_detection]
21+
# [START face_detection]
22+
# [START get_vision_service]
2223
use Google\Cloud\Vision\VisionClient;
2324

24-
// $apiKey = 'YOUR-API-KEY';
25+
// $projectId = 'YOUR_PROJECT_ID';
2526
// $path = 'path/to/your/image.jpg'
2627

2728
$vision = new VisionClient([
28-
'key' => $apiKey,
29+
'projectId' => $projectId,
2930
]);
31+
# [END get_vision_service]
32+
# [START detect_face]
3033
$image = $vision->image(file_get_contents($path), ['FACE_DETECTION']);
3134
$result = $vision->annotate($image);
32-
if (!isset($result->info()['faceAnnotations'])) {
33-
return;
34-
}
35-
foreach ($result->info()['faceAnnotations'] as $annotation) {
36-
print("FACE\n");
37-
if (isset($annotation['boundingPoly'])) {
38-
print(" BOUNDING POLY\n");
39-
foreach ($annotation['boundingPoly']['vertices'] as $vertex) {
40-
$x = isset($vertex['x']) ? $vertex['x'] : '';
41-
$y = isset($vertex['y']) ? $vertex['y'] : '';
42-
print(" x:$x\ty:$y\n");
35+
# [END detect_face]
36+
if (isset($result->info()['faceAnnotations'])) {
37+
foreach ($result->info()['faceAnnotations'] as $annotation) {
38+
print("FACE\n");
39+
if (isset($annotation['boundingPoly'])) {
40+
print(" BOUNDING POLY\n");
41+
foreach ($annotation['boundingPoly']['vertices'] as $vertex) {
42+
$x = isset($vertex['x']) ? $vertex['x'] : '';
43+
$y = isset($vertex['y']) ? $vertex['y'] : '';
44+
print(" x:$x\ty:$y\n");
45+
}
4346
}
44-
}
45-
if (isset($annotation['landmarks'])) {
46-
print(" LANDMARKS\n");
47-
foreach ($annotation['landmarks'] as $landmark) {
48-
$pos = $landmark['position'];
49-
print(" $landmark[type]:\tx:$pos[x]\ty:$pos[y]\tz:$pos[z]\n");
47+
if (isset($annotation['landmarks'])) {
48+
print(" LANDMARKS\n");
49+
foreach ($annotation['landmarks'] as $landmark) {
50+
$pos = $landmark['position'];
51+
print(" $landmark[type]:\tx:$pos[x]\ty:$pos[y]\tz:$pos[z]\n");
52+
}
5053
}
51-
}
52-
$scalar_features = [
53-
'rollAngle',
54-
'panAngle',
55-
'tiltAngle',
56-
'detectionConfidence',
57-
'landmarkingConfidence',
58-
'joyLikelihood',
59-
'sorrowLikelihood',
60-
'angerLikelihood',
61-
'surpriseLikelihood',
62-
'underExposedLikelihood',
63-
'blurredLikelihood',
64-
'headwearLikelihood'
65-
];
66-
foreach ($scalar_features as $feature) {
67-
if (isset($annotation[$feature])) {
68-
print(" $feature:\t$annotation[$feature]\n");
54+
$scalar_features = [
55+
'rollAngle',
56+
'panAngle',
57+
'tiltAngle',
58+
'detectionConfidence',
59+
'landmarkingConfidence',
60+
'joyLikelihood',
61+
'sorrowLikelihood',
62+
'angerLikelihood',
63+
'surpriseLikelihood',
64+
'underExposedLikelihood',
65+
'blurredLikelihood',
66+
'headwearLikelihood'
67+
];
68+
foreach ($scalar_features as $feature) {
69+
if (isset($annotation[$feature])) {
70+
print(" $feature:\t$annotation[$feature]\n");
71+
}
6972
}
7073
}
7174
}
72-
// [END face_detection]
75+
# [END face_detection]
76+
return $result;

vision/api/src/snippets/detect_label.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,29 @@
1515
* limitations under the License.
1616
*/
1717

18-
1918
namespace Google\Cloud\Samples\Vision;
2019

21-
// [START label_detection]
20+
# [START detect_labels]
21+
# [START import_libraries]
2222
use Google\Cloud\Vision\VisionClient;
2323

24-
// $apiKey = 'YOUR-API-KEY';
24+
# [END import_libraries]
25+
26+
// $projectId = 'YOUR_PROJECT_ID';
2527
// $path = 'path/to/your/image.jpg'
2628

29+
# [START authenticate]
2730
$vision = new VisionClient([
28-
'key' => $apiKey,
31+
'projectId' => $projectId,
2932
]);
33+
# [END authenticate]
34+
35+
# [START construct_request]
3036
$image = $vision->image(file_get_contents($path), ['LABEL_DETECTION']);
3137
$result = $vision->annotate($image);
38+
# [END construct_request]
39+
40+
# [START parse_response]
3241
if (!isset($result->info()['labelAnnotations'])) {
3342
return;
3443
}
@@ -38,4 +47,5 @@
3847
print(" description: $annotation[description]\n");
3948
print(" score: $annotation[score]\n");
4049
}
41-
// [END label_detection]
50+
# [END parse_response]
51+
# [END detect_labels]

vision/api/test/CommandTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,45 @@ public function testFaceCommandWithImageLackingFaces()
116116
$this->assertEquals('', $display);
117117
}
118118

119+
public function testFaceCommandWithOutput()
120+
{
121+
$application = new Application();
122+
$application->add(new DetectFaceCommand());
123+
$commandTester = new CommandTester($application->get('face'));
124+
$output = sys_get_temp_dir() . '/face.png';
125+
$commandTester->execute(
126+
[
127+
'path' => __DIR__ . '/data/face.png',
128+
'output' => $output,
129+
],
130+
['interactive' => false]
131+
);
132+
$this->assertEquals(0, $commandTester->getStatusCode());
133+
$display = $this->getActualOutput();
134+
$this->assertContains('NOSE_TIP', $display);
135+
$this->assertContains('angerLikelihood:', $display);
136+
$this->assertContains('Output image written to ' . $output, $display);
137+
$this->assertTrue(file_exists($output));
138+
}
139+
140+
public function testFaceCommandWithImageLackingFacesAndOutput()
141+
{
142+
$application = new Application();
143+
$application->add(new DetectFaceCommand());
144+
$commandTester = new CommandTester($application->get('face'));
145+
$output = sys_get_temp_dir() . '/face.png';
146+
$commandTester->execute(
147+
[
148+
'path' => __DIR__ . '/data/tower.jpg',
149+
'output' => $output,
150+
],
151+
['interactive' => false]
152+
);
153+
$this->assertEquals(0, $commandTester->getStatusCode());
154+
$display = $this->getActualOutput();
155+
$this->assertEquals('', $display);
156+
}
157+
119158
public function testLandmarkCommand()
120159
{
121160
$application = new Application();

0 commit comments

Comments
 (0)