質問編集履歴

3

問題点の訂正.

2021/01/19 01:51

投稿

porcini
porcini

スコア0

test CHANGED
File without changes
test CHANGED
@@ -10,7 +10,9 @@
10
10
 
11
11
  問題は, 検出された座標を取得して服の画像が表示することが出来ないという点で躓いています.
12
12
 
13
- 1つ目のソースコードの下部, 米印(*)の部分で服の画像を出力させようとしています.
13
+ 1つ目のソースコードの下部, **米印(*)**の部分で服の画像を出力させようとしています.
14
+
15
+ 動作としては, 上半身の認識が確認できた時にボタンを押し, Upper bodyの座標に服の画像を出力する。
14
16
 
15
17
  また, 2つ目のソースコードでは基本的に物体検出させる詳細が書かれています.
16
18
 

2

服の画像を出力するタイミングを、Buttonが押された時に動くように変更しました。それに伴い、Buttonの追加とソースコードの1部を変更しました。

2021/01/19 01:51

投稿

porcini
porcini

スコア0

test CHANGED
File without changes
test CHANGED
@@ -78,342 +78,350 @@
78
78
 
79
79
  **********************
80
80
 
81
- @IBOutlet weak var UIImageView: UIImageView!
81
+   @IBOutlet weak var UIImageView: UIImageView!
82
+
82
-
83
+   @IBAction func tapBtn(_ sender: Any) {
84
+
83
- func imageset(_ bounds: CGRect, identifier: String) -> UIImageView {
85
+ func imageset(_ bounds: CGRect, identifier: String) -> UIImageView {
86
+
87
+ let textLayer = CATextLayer()
88
+
89
+ let images = UIKit.UIImageView()
90
+
91
+ images.bounds = bounds
92
+
93
+ if textLayer.name == "Upper body"{
94
+
95
+ images.image = UIImage(named: "Upper body")
96
+
97
+ images.frame = CGRect(x: bounds.midX, y: bounds.midY, width:     bounds.size.height, height: bounds.size.width)
98
+
99
+ images.center = CGPoint(x: bounds.midX, y: bounds.minY)
100
+
101
+ self.view.addSubview(images)
102
+
103
+ }else{
104
+
105
+ print("error")
106
+
107
+ }
108
+
109
+ return images
110
+
111
+ }
112
+
113
+ }
114
+
115
+ ***********************
116
+
117
+ ```
118
+
119
+ ```Swift
120
+
121
+ import UIKit
122
+
123
+ import AVFoundation
124
+
125
+ import Vision
126
+
127
+
128
+
129
+ class VisionObjectRecognitionViewController: ViewController {
130
+
131
+
132
+
133
+ private var detectionOverlay: CALayer! = nil
134
+
135
+
136
+
137
+ // Visionパーツ
138
+
139
+ private var requests = [VNRequest]()
140
+
141
+
142
+
143
+ @discardableResult
144
+
145
+ func setupVision() -> NSError? {
146
+
147
+ // Visionパーツのセットアップ
148
+
149
+ let error: NSError! = nil
150
+
151
+
152
+
153
+ // MLモデルの指定, Visionモデルの指定
154
+
155
+ guard let modelURL = Bundle.main.url(forResource: "MyObjectDetector7", withExtension: "mlmodelc") else {
156
+
157
+ return NSError(domain: "VisionObjectRecognitionViewController", code: -1, userInfo: [NSLocalizedDescriptionKey: "Modelファイルがありません."])
158
+
159
+ }
160
+
161
+ do {
162
+
163
+ let visionModel = try VNCoreMLModel(for: MLModel(contentsOf: modelURL))
164
+
165
+ let objectRecognition = VNCoreMLRequest(model: visionModel, completionHandler: { (request, error) in
166
+
167
+ DispatchQueue.main.async(execute: {
168
+
169
+ // メインキューで全てのUI更新を実行
170
+
171
+ if let results = request.results {
172
+
173
+ self.drawVisionRequestResults(results)
174
+
175
+ }
176
+
177
+ })
178
+
179
+ })
180
+
181
+ self.requests = [objectRecognition]
182
+
183
+ } catch let error as NSError {
184
+
185
+ print("Modelが読み込めませんでした. (error)")
186
+
187
+ }
188
+
189
+
190
+
191
+ return error
192
+
193
+ }
194
+
195
+
196
+
197
+ func drawVisionRequestResults(_ results: [Any]) {
198
+
199
+ CATransaction.begin()
200
+
201
+ CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
202
+
203
+ detectionOverlay.sublayers = nil // 古い認識したオブジェクトの値を削除
204
+
205
+ for observation in results where observation is VNRecognizedObjectObservation {
206
+
207
+ guard let objectObservation = observation as? VNRecognizedObjectObservation else {
208
+
209
+ continue
210
+
211
+ }
212
+
213
+ // 最も信頼性の高いラベルのみを選択
214
+
215
+ let topLabelObservation = objectObservation.labels[0] //最も信頼度の高い値を選ぶ
216
+
217
+ let objectBounds = VNImageRectForNormalizedRect(objectObservation.boundingBox, Int(bufferSize.width), Int(bufferSize.height))
218
+
219
+
220
+
221
+ let shapeLayer = self.createRoundedRectLayerWithBounds(objectBounds)
222
+
223
+
224
+
225
+ let textLayer = self.createTextSubLayerInBounds(objectBounds,
226
+
227
+ identifier: topLabelObservation.identifier,
228
+
229
+ confidence: topLabelObservation.confidence)
230
+
231
+ shapeLayer.addSublayer(textLayer)
232
+
233
+ detectionOverlay.addSublayer(shapeLayer)
234
+
235
+ }
236
+
237
+ self.updateLayerGeometry()
238
+
239
+ CATransaction.commit()
240
+
241
+ }
242
+
243
+
244
+
245
+ override func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
246
+
247
+ guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
248
+
249
+ return
250
+
251
+ }
252
+
253
+
254
+
255
+ let exifOrientation = exifOrientationFromDeviceOrientation()
256
+
257
+
258
+
259
+ let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: exifOrientation, options: [:])
260
+
261
+ do {
262
+
263
+ try imageRequestHandler.perform(self.requests)
264
+
265
+ } catch {
266
+
267
+ print(error)
268
+
269
+ }
270
+
271
+ }
272
+
273
+
274
+
275
+ override func setupAVCapture() {
276
+
277
+ super.setupAVCapture()
278
+
279
+
280
+
281
+ // セットアップVisionパーツ
282
+
283
+ setupLayers()
284
+
285
+ updateLayerGeometry()
286
+
287
+ setupVision()
288
+
289
+
290
+
291
+ // キャプチャセッションをスタート
292
+
293
+ startCaptureSession()
294
+
295
+ }
296
+
297
+
298
+
299
+ func setupLayers() {
300
+
301
+ detectionOverlay = CALayer() // 観測された全てのコンテナレイヤー(レンダリングを含む)
302
+
303
+ detectionOverlay.name = "DetectionOverlay"
304
+
305
+ detectionOverlay.bounds = CGRect(x: 0.0,
306
+
307
+ y: 0.0,
308
+
309
+ width: bufferSize.width,
310
+
311
+ height: bufferSize.height)
312
+
313
+ detectionOverlay.position = CGPoint(x: rootLayer.bounds.midX, y: rootLayer.bounds.midY)
314
+
315
+ rootLayer.addSublayer(detectionOverlay)
316
+
317
+ }
318
+
319
+
320
+
321
+ func updateLayerGeometry() {
322
+
323
+ let bounds = rootLayer.bounds
324
+
325
+ var scale: CGFloat
326
+
327
+
328
+
329
+ let xScale: CGFloat = bounds.size.width / bufferSize.height
330
+
331
+ let yScale: CGFloat = bounds.size.height / bufferSize.width
332
+
333
+
334
+
335
+ scale = fmax(xScale, yScale)
336
+
337
+ if scale.isInfinite {
338
+
339
+ scale = 1.0
340
+
341
+ }
342
+
343
+ CATransaction.begin()
344
+
345
+ CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
346
+
347
+
348
+
349
+ //レイヤーを画面の向きにし, スケールとミラーリング
350
+
351
+ detectionOverlay.setAffineTransform(CGAffineTransform(rotationAngle: CGFloat(.pi / 2.0)).scaledBy(x: scale, y: -scale))
352
+
353
+ //レーヤーを中央に配置
354
+
355
+ detectionOverlay.position = CGPoint(x: bounds.midX, y: bounds.midY)
356
+
357
+
358
+
359
+ CATransaction.commit()
360
+
361
+
362
+
363
+ }
364
+
365
+
366
+
367
+ func createTextSubLayerInBounds(_ bounds: CGRect, identifier: String, confidence: VNConfidence) -> CATextLayer {
84
368
 
85
369
  let textLayer = CATextLayer()
86
370
 
87
- let images = UIKit.UIImageView()
88
-
89
- images.bounds = bounds
90
-
91
- if textLayer.name == "Upper body"{
371
+ textLayer.name = "Object Label"
372
+
92
-
373
+ let formattedString = NSMutableAttributedString(string: String(format: "(identifier)\nConfidence: %.2f", confidence))
374
+
93
- images.image = UIImage(named: "Upper body")
375
+ let largeFont = UIFont(name: "Helvetica", size: 24.0)!
376
+
94
-
377
+ formattedString.addAttributes([NSAttributedString.Key.font: largeFont], range: NSRange(location: 0, length: identifier.count))
378
+
379
+ textLayer.string = formattedString
380
+
95
- images.frame = CGRect(x: bounds.midX, y: bounds.midY, width: bounds.size.height, height: bounds.size.width)
381
+ textLayer.bounds = CGRect(x: 0, y: 0, width: bounds.size.height - 10, height: bounds.size.width - 10)
96
-
382
+
97
- images.center = CGPoint(x: bounds.midX, y: bounds.minY)
383
+ textLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
98
-
384
+
99
- self.view.addSubview(images)
385
+ textLayer.shadowOpacity = 0.7
386
+
100
-
387
+ textLayer.shadowOffset = CGSize(width: 2, height: 2)
388
+
389
+ textLayer.foregroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [0.0, 0.0, 0.0, 1.0])
390
+
391
+ textLayer.contentsScale = 2.0 // retina rendering
392
+
393
+ //レイヤーを画面の向きに回転させ, 拡大縮小してミラーリングする
394
+
395
+ textLayer.setAffineTransform(CGAffineTransform(rotationAngle: CGFloat(.pi / 2.0)).scaledBy(x: 1.0, y: -1.0))
396
+
397
+ return textLayer
398
+
101
- }
399
+ }
400
+
401
+
402
+
102
-
403
+ //認識した座標に矩形を表示
404
+
405
+ func createRoundedRectLayerWithBounds(_ bounds: CGRect) -> CALayer {
406
+
407
+ let shapeLayer = CALayer()
408
+
409
+ shapeLayer.bounds = bounds
410
+
411
+ shapeLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
412
+
413
+ shapeLayer.name = "Found Object"
414
+
415
+ shapeLayer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [1.0, 1.0, 1.0, 0.4])
416
+
417
+ shapeLayer.cornerRadius = 7
418
+
103
- return images
419
+ return shapeLayer
104
-
420
+
105
- }
421
+ }
106
-
422
+
107
- ***********************
423
+ }
424
+
425
+
108
426
 
109
427
  ```
110
-
111
- ```Swift
112
-
113
- import UIKit
114
-
115
- import AVFoundation
116
-
117
- import Vision
118
-
119
-
120
-
121
- class VisionObjectRecognitionViewController: ViewController {
122
-
123
-
124
-
125
- private var detectionOverlay: CALayer! = nil
126
-
127
-
128
-
129
- // Visionパーツ
130
-
131
- private var requests = [VNRequest]()
132
-
133
-
134
-
135
- @discardableResult
136
-
137
- func setupVision() -> NSError? {
138
-
139
- // Visionパーツのセットアップ
140
-
141
- let error: NSError! = nil
142
-
143
-
144
-
145
- // MLモデルの指定, Visionモデルの指定
146
-
147
- guard let modelURL = Bundle.main.url(forResource: "MyObjectDetector7", withExtension: "mlmodelc") else {
148
-
149
- return NSError(domain: "VisionObjectRecognitionViewController", code: -1, userInfo: [NSLocalizedDescriptionKey: "Modelファイルがありません."])
150
-
151
- }
152
-
153
- do {
154
-
155
- let visionModel = try VNCoreMLModel(for: MLModel(contentsOf: modelURL))
156
-
157
- let objectRecognition = VNCoreMLRequest(model: visionModel, completionHandler: { (request, error) in
158
-
159
- DispatchQueue.main.async(execute: {
160
-
161
- // メインキューで全てのUI更新を実行
162
-
163
- if let results = request.results {
164
-
165
- self.drawVisionRequestResults(results)
166
-
167
- }
168
-
169
- })
170
-
171
- })
172
-
173
- self.requests = [objectRecognition]
174
-
175
- } catch let error as NSError {
176
-
177
- print("Modelが読み込めませんでした. (error)")
178
-
179
- }
180
-
181
-
182
-
183
- return error
184
-
185
- }
186
-
187
-
188
-
189
- func drawVisionRequestResults(_ results: [Any]) {
190
-
191
- CATransaction.begin()
192
-
193
- CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
194
-
195
- detectionOverlay.sublayers = nil // 古い認識したオブジェクトの値を削除
196
-
197
- for observation in results where observation is VNRecognizedObjectObservation {
198
-
199
- guard let objectObservation = observation as? VNRecognizedObjectObservation else {
200
-
201
- continue
202
-
203
- }
204
-
205
- // 最も信頼性の高いラベルのみを選択
206
-
207
- let topLabelObservation = objectObservation.labels[0] //最も信頼度の高い値を選ぶ
208
-
209
- let objectBounds = VNImageRectForNormalizedRect(objectObservation.boundingBox, Int(bufferSize.width), Int(bufferSize.height))
210
-
211
-
212
-
213
- let shapeLayer = self.createRoundedRectLayerWithBounds(objectBounds)
214
-
215
-
216
-
217
- let textLayer = self.createTextSubLayerInBounds(objectBounds,
218
-
219
- identifier: topLabelObservation.identifier,
220
-
221
- confidence: topLabelObservation.confidence)
222
-
223
- shapeLayer.addSublayer(textLayer)
224
-
225
- detectionOverlay.addSublayer(shapeLayer)
226
-
227
- }
228
-
229
- self.updateLayerGeometry()
230
-
231
- CATransaction.commit()
232
-
233
- }
234
-
235
-
236
-
237
- override func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
238
-
239
- guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
240
-
241
- return
242
-
243
- }
244
-
245
-
246
-
247
- let exifOrientation = exifOrientationFromDeviceOrientation()
248
-
249
-
250
-
251
- let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: exifOrientation, options: [:])
252
-
253
- do {
254
-
255
- try imageRequestHandler.perform(self.requests)
256
-
257
- } catch {
258
-
259
- print(error)
260
-
261
- }
262
-
263
- }
264
-
265
-
266
-
267
- override func setupAVCapture() {
268
-
269
- super.setupAVCapture()
270
-
271
-
272
-
273
- // セットアップVisionパーツ
274
-
275
- setupLayers()
276
-
277
- updateLayerGeometry()
278
-
279
- setupVision()
280
-
281
-
282
-
283
- // キャプチャセッションをスタート
284
-
285
- startCaptureSession()
286
-
287
- }
288
-
289
-
290
-
291
- func setupLayers() {
292
-
293
- detectionOverlay = CALayer() // 観測された全てのコンテナレイヤー(レンダリングを含む)
294
-
295
- detectionOverlay.name = "DetectionOverlay"
296
-
297
- detectionOverlay.bounds = CGRect(x: 0.0,
298
-
299
- y: 0.0,
300
-
301
- width: bufferSize.width,
302
-
303
- height: bufferSize.height)
304
-
305
- detectionOverlay.position = CGPoint(x: rootLayer.bounds.midX, y: rootLayer.bounds.midY)
306
-
307
- rootLayer.addSublayer(detectionOverlay)
308
-
309
- }
310
-
311
-
312
-
313
- func updateLayerGeometry() {
314
-
315
- let bounds = rootLayer.bounds
316
-
317
- var scale: CGFloat
318
-
319
-
320
-
321
- let xScale: CGFloat = bounds.size.width / bufferSize.height
322
-
323
- let yScale: CGFloat = bounds.size.height / bufferSize.width
324
-
325
-
326
-
327
- scale = fmax(xScale, yScale)
328
-
329
- if scale.isInfinite {
330
-
331
- scale = 1.0
332
-
333
- }
334
-
335
- CATransaction.begin()
336
-
337
- CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
338
-
339
-
340
-
341
- //レイヤーを画面の向きにし, スケールとミラーリング
342
-
343
- detectionOverlay.setAffineTransform(CGAffineTransform(rotationAngle: CGFloat(.pi / 2.0)).scaledBy(x: scale, y: -scale))
344
-
345
- //レーヤーを中央に配置
346
-
347
- detectionOverlay.position = CGPoint(x: bounds.midX, y: bounds.midY)
348
-
349
-
350
-
351
- CATransaction.commit()
352
-
353
-
354
-
355
- }
356
-
357
-
358
-
359
- func createTextSubLayerInBounds(_ bounds: CGRect, identifier: String, confidence: VNConfidence) -> CATextLayer {
360
-
361
- let textLayer = CATextLayer()
362
-
363
- textLayer.name = "Object Label"
364
-
365
- let formattedString = NSMutableAttributedString(string: String(format: "(identifier)\nConfidence: %.2f", confidence))
366
-
367
- let largeFont = UIFont(name: "Helvetica", size: 24.0)!
368
-
369
- formattedString.addAttributes([NSAttributedString.Key.font: largeFont], range: NSRange(location: 0, length: identifier.count))
370
-
371
- textLayer.string = formattedString
372
-
373
- textLayer.bounds = CGRect(x: 0, y: 0, width: bounds.size.height - 10, height: bounds.size.width - 10)
374
-
375
- textLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
376
-
377
- textLayer.shadowOpacity = 0.7
378
-
379
- textLayer.shadowOffset = CGSize(width: 2, height: 2)
380
-
381
- textLayer.foregroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [0.0, 0.0, 0.0, 1.0])
382
-
383
- textLayer.contentsScale = 2.0 // retina rendering
384
-
385
- //レイヤーを画面の向きに回転させ, 拡大縮小してミラーリングする
386
-
387
- textLayer.setAffineTransform(CGAffineTransform(rotationAngle: CGFloat(.pi / 2.0)).scaledBy(x: 1.0, y: -1.0))
388
-
389
- return textLayer
390
-
391
- }
392
-
393
-
394
-
395
- //認識した座標に矩形を表示
396
-
397
- func createRoundedRectLayerWithBounds(_ bounds: CGRect) -> CALayer {
398
-
399
- let shapeLayer = CALayer()
400
-
401
- shapeLayer.bounds = bounds
402
-
403
- shapeLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
404
-
405
- shapeLayer.name = "Found Object"
406
-
407
- shapeLayer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [1.0, 1.0, 1.0, 0.4])
408
-
409
- shapeLayer.cornerRadius = 7
410
-
411
- return shapeLayer
412
-
413
- }
414
-
415
- }
416
-
417
-
418
-
419
- ```

1

使用しているサンプルプログラムのリンクを追記しました.

2021/01/15 12:27

投稿

porcini
porcini

スコア0

test CHANGED
File without changes
test CHANGED
@@ -16,6 +16,10 @@
16
16
 
17
17
  カメラセッションなどは省力します。
18
18
 
19
+ **以下のサンプルに手を加えて, 画像を出力出来るように考えています.**
20
+
21
+ 【https://developer.apple.com/documentation/vision/recognizing_objects_in_live_capture】
22
+
19
23
  ### 該当のソースコード
20
24
 
21
25
  ```Swift