質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

487閲覧

swiftにてグレー化し、さらに数値化する

NIGG

総合スコア10

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/01/16 08:27

編集2022/01/12 10:55

前提・実現したいこと

swift・プログラミング初心者です。

該当のソースコードは連写機能のカメラアプリのコードです。
そのソースコード内の↓↑の間にUIimageをグレー化し、
一枚ずつ数値を出せるようなコード入れたいのですが…
(関数を追加、UIImageを呼び出して計算…etc)

『試したこと』にあるコードではグレー化、数値化はともにできています。
そこでそれらのコードを使い、グレー化、数値化機能を導入しようと考えています。
ですがそのコードをどのように書き換え、追加すればいいのかわからない状況です。

※↓↑内は『試したこと』欄にあるコードなどを使えないかと思い書いただけです。

どうかご教示お願いいたします。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

class ViewController: UIViewController ,AVCaptureVideoDataOutputSampleBufferDelegate,AVAudioPlayerDelegate { @IBOutlet weak var previewView: UIImageView! @IBOutlet weak var snapButton: UIButton! @IBOutlet weak var scrollView: UIScrollView! var videoDataOutput: AVCaptureVideoDataOutput? var images:[UIImage] = [] var isShooting = false // 連写中 var counter = 0 var audioPlayer:AVAudioPlayer! // シャッター音用 override func viewDidLoad() { super.viewDidLoad() // シャッター音 let audioPath = Bundle.main.path(forResource: "nc66359", ofType:"wav")! //再生する音源のURL let audioUrl = URL(fileURLWithPath: audioPath) audioPlayer = try! AVAudioPlayer(contentsOf: audioUrl) audioPlayer.delegate = self //デリゲートセット audioPlayer.currentTime = 0 // セッションのインスタンス生成 let captureSession = AVCaptureSession() //設定 // 入力(背面カメラ) let videoDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) videoDevice?.activeVideoMinFrameDuration = CMTimeMake(1, 30)// フレームレート 1/30秒 let videoInput = try! AVCaptureDeviceInput.init(device: videoDevice) captureSession.addInput(videoInput) // 出力(ビデオデータ) videoDataOutput = AVCaptureVideoDataOutput() // ピクセルフォーマット(32bit BGRA) videoDataOutput?.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable : Int(kCVPixelFormatType_32BGRA)]//色情報 // キューのブロック中に新しいフレームが来たら削除する videoDataOutput?.alwaysDiscardsLateVideoFrames = true // フレームをキャプチャするためのキューを指定 videoDataOutput?.setSampleBufferDelegate(self, queue: DispatchQueue.main) captureSession.addOutput(videoDataOutput) // クオリティ(1920x1080ピクセル) captureSession.sessionPreset = AVCaptureSessionPreset1920x1080//画像の質 // プレビュー if let videoLayer = AVCaptureVideoPreviewLayer.init(session: captureSession) { videoLayer.frame = previewView.bounds videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill previewView.layer.addSublayer(videoLayer) } // セッションの開始 DispatchQueue.global(qos: .userInitiated).async { captureSession.startRunning() } } // 新しいキャプチャの追加で呼ばれる(1/30秒に1回) func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { if counter % 3 == 0 { // 1/10秒だけ処理する if isShooting { // let image:UIImage = captureImage(sampleBuffer) //let image = UIImage(named: "003.jpg") let image = imageFromSampleBuffer(sampleBuffer: sampleBuffer) addImage(image: image) } } counter += 1 } ↓↓↓ func ImageData(){ let image = Image<RGBA<UInt8>>(uiImage: imageView.image!) var x,y:Int x = 0 y = 0 var sum:Int = 0 for x in 0..<photowidth { for y in 0..<photoheight { sum = sum + (image[x,y].gray as AnyObject as! Int) } } var average = sum / photosize print("ave:", average) } ↑↑↑ @IBAction func touchUpButton(_ sender: UIButton) { isShooting = false // 連写終了 audioPlayer.stop() } @IBAction func touchDownButton(_ sender: UIButton) { // 前回撮影の画像を削除 images = [] for imageView in scrollView.subviews { imageView.removeFromSuperview() } isShooting = true // 連写中 audioPlayer.play() } // 連写音の連続再生 func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { if isShooting { audioPlayer.play() } } //CMSampleBufferをUIImageに変換する func imageFromSampleBuffer(sampleBuffer :CMSampleBuffer) -> UIImage { let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! // サンプルバッファからimageバッファを取り出す // イメージバッファのロック CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) // 画像情報を取得 let base = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0)! let bytesPerRow = UInt(CVPixelBufferGetBytesPerRow(imageBuffer)) let width = UInt(CVPixelBufferGetWidth(imageBuffer)) let height = UInt(CVPixelBufferGetHeight(imageBuffer)) // ビットマップコンテキスト作成 let colorSpace = CGColorSpaceCreateDeviceRGB() let bitsPerCompornent = 8 let bitmapInfo = CGBitmapInfo(rawValue: (CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) as UInt32) let newContext = CGContext(data: base, width: Int(width), height: Int(height), bitsPerComponent: Int(bitsPerCompornent), bytesPerRow: Int(bytesPerRow), space: colorSpace, bitmapInfo: bitmapInfo.rawValue)! as CGContext // 画像作成 let imageRef = newContext.makeImage()! let image = UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.right) // イメージバッファのアンロック CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) return image } func addImage(image: UIImage) { let height:CGFloat = 100 // 基準の高さ let margin = 10 let magnification = height / image.size.height let width = image.size.width * magnification let x = (margin + Int(width)) * images.count let y = margin let imageView = UIImageView(image: image) imageView.frame = CGRect(x: x, y: y, width: Int(width), height: Int(height)) scrollView.addSubview(imageView) let w = x + Int(width) scrollView.contentSize = CGSize(width: CGFloat(w), height: scrollView.frame.size.height) images.append(image) } }

試したこと

import UIKit
import EasyImagy

class ViewController: UIViewController {

override func viewDidLoad() { super.viewDidLoad() // 画面に出る子供の画像はプロジェクトに組み込み済み。 Main.storyboard で指定している initImageView() } func initImageView(){ print("(in initImageView) ") // 画像データファイルの読み込み:Main.storyboard に指定したものと同一 let imageUI1:UIImage = UIImage(named:"Baby1x.jpg")! // サイズは 593x896 let imageView = UIImageView(image:imageUI1) /* // 画面の中心を求めて let screenWidth:CGFloat = view.frame.size.width let screenHeight:CGFloat = view.frame.size.height imageView.center = CGPoint(x:screenWidth/2, y:screenHeight/2) // 下の行を実行すれば Main.storyboard に指定しなくても表示される? //self.view.addSubview(imageView) */ let photowidth = imageUI1.size.width as AnyObject as! Int let photoheight = imageUI1.size.height as AnyObject as! Int let photosize = photowidth * photoheight print(photosize) print(photoheight) print(photowidth) // Image にデータを代入 let myimage = Image<RGBA<UInt8>>(uiImage: imageView.image!) var x,y:Int x = 0 y = 0 //myimage[x,y]のデータをRGBAで表示する print( myimage[x,y] ) print( myimage[250,450] ) print( myimage[592,895] ) print( myimage[592,895].gray) //print( myimage[895,592] ) // 配列からはみ出でてエラーになる var sum:Int = 0 for x in 0..<photowidth { for y in 0..<photoheight { sum = sum + (myimage[x,y].gray as AnyObject as! Int) } } var average = sum / photosize print("ave:", average) print("(end of initImageView)") }

}

補足情報(FW/ツールのバージョンなど)

EasyImageというフレームワークを使わせていただいています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takabosoft

2019/01/16 08:38

どこでつまづいているのでしょうか?
NIGG

2019/01/16 09:46

該当のソースコードの↓↑内に、試したこと欄にあるコード等を使って数値を計算できるようにしたいのですが、どのようにコーディングしていけばいいかなど初歩的なことですがわかりません。 初歩的なことで申し訳ありませんが、コードに流れの説明をつけていただけると幸いです。
guest

回答1

0

躓いているポイントがよく判らないので、ほとんど推測ですが、

とりあえず組み込んだであろうfunc ImageData(){はおそらく正しく関数化できていません。

入力を画像(UIImage型)とし、出力をグレーの平均値となるように正しく書き直してください。
名前ももう少し関数の役割が判るような名前を付けてください。

例えば

swift

1/// 画像のグレースケール値の平均を求めます。 2func calcGrayAverage(image: UIImage) -> Int { 3 // TODO: ここは頑張って書いてください。 4}

という関数を完成させてください。

開発の手順としては「試したこと」の方のプロジェクトを改造して
initImageView関数にかかれている一部をcalcGrayAverageとして抽出&関数化し、再利用できる形に加工してみると良いでしょう。

つまり、「試したこと」のコードの
print("ave:", average)
という部分を
print("ave:", calcGrayAverage(image: imageView.image!))
と関数呼び出しに変えて同じ値が出るようなcalcGrayAverage関数を作るという意味です。

それが上手く行ったら、「該当のソースコード」の方へ関数をコピペし、呼び出して使うことができるはずです。

投稿2019/01/17 00:25

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問