import numpy as np def hist_match ( source , template ): """ Adjust the pixel values of a grayscale image such that its histogram matches that of a target image Arguments: ----------- source: np.ndarray Image to transform; the histogram is computed over the flattened array template: np.ndarray Template image; can have different dimensions to source Returns: ----------- matched: np.ndarray The transformed output image """ oldshape = source . shape source = source . ravel () template = template . ravel () # get the set of unique pixel values and their corresponding indices and # counts s_values , bin_idx , s_counts = np . unique ( source , return_inverse = True , return_counts = True ) t_values , t_counts = np . unique ( template , return_counts = True ) ...
#pragma once
답글삭제#include "ofMain.h"
#include "ofxKerasify.h" // 케라스 모델을 C++로 바꿔주는 라이브러리.
class ofApp : public ofBaseApp{
public:
...
void infer(); // 추론 메써드 프로토타입.
ofxKerasify kerasify; // 인스턴스
// prediction result
std::vector output; // 출력 벡터
int predicted_number; // mnist 예측값 정수
private:
void clear(); // 지우시 메써드, 왜 프라이빗?
bool needsClear; // 지울지 여부
float pmouseX, pmouseY; // 마우스 위치
};
//???: 화면 초기화 및 학습모델 로딩.
답글삭제void ofApp::setup(){
ofSetBackgroundAuto(false);
ofSetWindowShape(600, 400);
needsClear = true; // for initializing view
// Load kerasified keras model
// dont't forget to convert keras model into kerasify model
kerasify.loadModel("mnist_mlp.model");
}
//???: 화면내 mnist이미지 캡쳐, 이미지 벡터화, 예측으로 추론, 최대출력을 숫자로 치환
답글삭제void ofApp::infer(){
// Grab image
ofImage img;
img.grabScreen(50, 100, 280, 280);
img.resize(28, 28);
img.setImageType(OF_IMAGE_GRAYSCALE);
// Image -> vector
ofPixels pix = img.getPixels();
std::vector input;
for (int i = 0; i < pix.size(); i++){
input.push_back(pix.getData()[i]/255.0);
}
// INFERENCE
std::vector input_dim{28 * 28};
std::vector output_dim{10};
output.resize(10);// output vector should be [10]. because we have 10 digits! ;-)
kerasify.predict(input_dim, input, output_dim, output);
// Get result
std::vector::iterator maxIt = std::max_element(output.begin(), output.end());
size_t maxIndex = std::distance(output.begin(), maxIt);
predicted_number = maxIndex; // result
}
//???: 지우기여부가 트루면 화면지우기
답글삭제void ofApp::update(){
if (needsClear) clear();
}
//???: 마우스로 숫자 그리기, 예측결과 디스플레이
답글삭제void ofApp::draw(){
if (needsClear) clear();
// Canvas
ofSetColor(255);
ofSetLineWidth(10);
ofDrawBitmapString("MNIST Inference", 20, 20);
ofDrawBitmapString("press RETURN to infer", 20, 40);
ofDrawBitmapString("press SPACE to clear", 20, 60);
if (ofGetMousePressed() == true){
float mouseX = ofGetMouseX();
float mouseY = ofGetMouseY();
ofDrawLine(mouseX, mouseY, pmouseX, pmouseY);
pmouseX = mouseX;
pmouseY = mouseY;
}
// Show Result
if (output.size() > 0){
ofDrawBitmapString("INFERED NUMBER: " + ofToString(predicted_number), 400, 100);
float min = *std::min_element(output.begin(), output.end());
float max = *std::max_element(output.begin(), output.end());
for (int i = 0; i < output.size(); i++){
if (i == predicted_number) ofSetColor(255, 100, 100);
else ofSetColor(200);
float w = 100. * (output[i] - min)/(max - min) + 20.;
ofDrawBitmapString(ofToString(i), 400, 160 + 20 * i);
ofDrawRectangle(420, 150 + 20 * i, w, 10);
}
}
}
//???: 화면 및 추론결과 초기화
답글삭제void ofApp::clear(){
ofBackground(100);
ofSetColor(0);
ofDrawRectangle(50, 100, 280, 280);
needsClear = false;
output.resize(0);
predicted_number = -1;
}
//???: 리턴키를 누르면 추론 메써드 호출, 다른키면 화면 삭제.
답글삭제void ofApp::keyPressed(int key){
if (key == OF_KEY_RETURN){
infer();
} else if (key == ' '){
needsClear = true;
}
}
//???: 마우스가 눌렸을때만 위치좌표 취득.
답글삭제void ofApp::mousePressed(int x, int y, int button){
// 글로벌 멤버변수, 왜 프라이빗?
pmouseX = ofGetMouseX();
pmouseY = ofGetMouseY();
}