[API] Python API와 Java 클라이언트를 이용한 CPK 분석 및 히스토그램 생성

2024. 7. 19. 08:44·자바

안녕하세요, 오늘은 Python으로 CPK(공정 능력 지수) 계산과 히스토그램 생성을 위한 API를 만들고, 이를 Java에서 호출하여 결과를 시각화하는 방법에 대해 알아보겠습니다.

1. 배경

제조 공정에서 CPK는 공정의 능력을 평가하는 중요한 지표입니다. 하지만 CPK 계산과 관련 데이터의 시각화는 복잡한 통계 처리가 필요합니다. Python은 이러한 데이터 처리와 시각화에 강점이 있어, Python으로 API를 구현하고 Java 백엔드에서 이를 호출하는 방식을 선택했습니다.

2. Python API 구현

먼저, Flask를 사용하여 CPK 계산과 히스토그램 생성을 위한 API를 구현했습니다.

# Python API 코드 (주요 부분만 발췌)

def calculate_cpk(data, lsl, usl):
    mean = np.mean(data)
    std = np.std(data, ddof=1)
    cpu = (usl - mean) / (3 * std)
    cpl = (mean - lsl) / (3 * std)
    cpk = min(cpu, cpl)
    return cpk

def generate_histogram(data, lsl, usl):
    plt.figure(figsize=(10, 6))
    plt.hist(data, bins=30, edgecolor='black')
    plt.axvline(lsl, color='r', linestyle='dashed', linewidth=2, label='LSL')
    plt.axvline(usl, color='r', linestyle='dashed', linewidth=2, label='USL')
    # ... (히스토그램 생성 코드)

@app.route('/calculate_cpk', methods=['POST'])
def api_calculate_cpk():
    # ... (API 엔드포인트 구현)

이 API는 측정 데이터, LSL(Lower Specification Limit), USL(Upper Specification Limit)을 입력받아 CPK 값과 히스토그램을 반환합니다.

3. Java 클라이언트 구현

다음으로, Java에서 위 API를 호출하고 결과를 처리하는 클라이언트를 구현했습니다.

public class CPKAnalyzer {
    private static final String API_URL = "http://localhost:5000/calculate_cpk";

    public static void main(String[] args) {
        // ... (메인 메소드 구현)
    }

    private static String sendPostRequest(String url, String json) throws Exception {
        // ... (HTTP POST 요청 구현)
    }

    private static void displayHistogram(String base64Image) throws Exception {
        // ... (히스토그램 표시 구현)
    }
}

이 클라이언트는 측정 데이터를 API에 전송하고, 반환받은 CPK 값과 히스토그램을 처리합니다.

4. 작동 방식

  1. Java 클라이언트에서 측정 데이터, LSL, USL을 준비합니다.
  2. 이 데이터를 JSON 형태로 변환하여 Python API에 POST 요청을 보냅니다.
  3. Python API는 데이터를 처리하여 CPK를 계산하고 히스토그램을 생성합니다.
  4. 계산된 CPK 값과 Base64로 인코딩된 히스토그램 이미지를 JSON 형태로 반환합니다.
  5. Java 클라이언트는 이 결과를 받아 CPK 값을 출력하고 히스토그램을 화면에 표시합니다.

5. 장점

  • Python의 강력한 데이터 처리 및 시각화 기능을 활용할 수 있습니다.
  • Java 백엔드와 Python 스크립트를 효과적으로 연동할 수 있습니다.
  • API 방식으로 구현하여 확장성과 재사용성이 높습니다.

6. 주의사항

  • API 서버와 클라이언트 간의 네트워크 지연을 고려해야 합니다.
  • 대용량 데이터 처리 시 메모리 사용량에 주의해야 합니다.
  • 보안을 위해 API 인증 메커니즘을 추가로 구현해야 할 수 있습니다.

7. 풀코드

파이썬

from flask import Flask, request, jsonify
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import io
import base64

app = Flask(__name__)

def calculate_cpk(data, lsl, usl):
    """
    CPK(Process Capability Index) 계산
    :param data: 측정 데이터
    :param lsl: Lower Specification Limit
    :param usl: Upper Specification Limit
    :return: CPK 값
    """
    mean = np.mean(data)
    std = np.std(data, ddof=1)
    cpu = (usl - mean) / (3 * std)
    cpl = (mean - lsl) / (3 * std)
    cpk = min(cpu, cpl)
    return cpk

def calculate_mean(data, lsl, usl):
    """평균 계산"""
    return np.mean(data)

def calculate_std(data, lsl, usl):
    """표준편차 계산"""
    return np.std(data, ddof=1)

def calculate_cpu(data, lsl, usl):
    """CPU(Capability Process Upper) 계산"""
    mean = np.mean(data)
    std = np.std(data, ddof=1)
    return (usl - mean) / (3 * std)

def calculate_cpl(data, lsl, usl):
    """CPL(Capability Process Lower) 계산"""
    mean = np.mean(data)
    std = np.std(data, ddof=1)
    return (mean - lsl) / (3 * std)

def generate_histogram(data, lsl, usl):
    """
    히스토그램 생성 및 Base64 인코딩된 이미지 반환
    :param data: 측정 데이터
    :param lsl: Lower Specification Limit
    :param usl: Upper Specification Limit
    :return: Base64 인코딩된 히스토그램 이미지
    """
    plt.figure(figsize=(10, 6))
    plt.hist(data, bins=30, edgecolor='black')
    plt.axvline(lsl, color='r', linestyle='dashed', linewidth=2, label='LSL')
    plt.axvline(usl, color='r', linestyle='dashed', linewidth=2, label='USL')
    plt.xlabel('Value')
    plt.ylabel('Frequency')
    plt.title('Histogram with LSL and USL')
    plt.legend()

    img = io.BytesIO()
    plt.savefig(img, format='png')
    img.seek(0)
    return base64.b64encode(img.getvalue()).decode()

@app.route('/calculate_cpk', methods=['POST'])
def api_calculate_cpk():
    """
    CPK 계산 및 히스토그램 생성 API 엔드포인트
    :return: CPK 값, 히스토그램, 기타 통계 정보를 포함한 JSON 응답
    """
    data = request.json
    measurements = data['measurements']
    lsl = data['lsl']
    usl = data['usl']

    mean = calculate_mean(measurements, lsl, usl)
    std = calculate_std(measurements, lsl, usl)
    cpu = calculate_cpu(measurements, lsl, usl)
    cpl = calculate_cpl(measurements, lsl, usl)
    cpk = calculate_cpk(measurements, lsl, usl)
    histogram = generate_histogram(measurements, lsl, usl)

    return jsonify({
        'lsl': lsl,
        'usl': usl,
        'mean': mean,
        'std': std,
        'cpu': cpu,
        'cpl': cpl,        
        'cpk': cpk,
        'histogram': histogram
    })

if __name__ == '__main__':
    app.run(debug=True)

자바

import org.json.JSONObject;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.Base64;
import javax.imageio.ImageIO;

public class CPKAnalyzer {
    private static final String API_URL = "http://localhost:5000/calculate_cpk";

    public static void main(String[] args) {
        try {
            // 측정 데이터 준비
            double[] measurements = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0};
            double lsl = 1.0;
            double usl = 2.0;

            // API 요청 데이터 생성
            JSONObject requestData = new JSONObject();
            requestData.put("measurements", measurements);
            requestData.put("lsl", lsl);
            requestData.put("usl", usl);

            // API 호출
            String response = sendPostRequest(API_URL, requestData.toString());
            JSONObject result = new JSONObject(response);

            // 결과 출력
            System.out.println("CPK: " + result.getDouble("cpk"));
            System.out.println("Mean: " + result.getDouble("mean"));
            System.out.println("Std Dev: " + result.getDouble("std"));

            // 히스토그램 표시
            displayHistogram(result.getString("histogram"));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String sendPostRequest(String url, String json) throws Exception {
        try (CloseableHttpClient client = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            StringEntity entity = new StringEntity(json);
            httpPost.setEntity(entity);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            return EntityUtils.toString(client.execute(httpPost).getEntity());
        }
    }

    private static void displayHistogram(String base64Image) throws Exception {
        byte[] imageBytes = Base64.getDecoder().decode(base64Image);
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));

        JFrame frame = new JFrame();
        frame.setSize(800, 600);
        JLabel label = new JLabel(new ImageIcon(image));
        frame.add(label);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

8. 결론

이 방식을 통해 Java 백엔드 시스템에서 Python의 강력한 데이터 분석 기능을 활용할 수 있게 되었습니다. CPK 분석뿐만 아니라 다양한 통계 분석 및 시각화 작업에도 이 패턴을 적용할 수 있을 것입니다.
앞으로 이 시스템을 개선하여 실시간 데이터 처리, 더 다양한 통계 지표 계산, 그리고 머신러닝 모델을 활용한 예측 분석 등으로 확장할 수 있을 것입니다. 또한, 웹 기반 대시보드를 구현하여 사용자가 더 쉽게 결과를 확인하고 분석할 수 있도록 할 계획입니다.

'자바' 카테고리의 다른 글

[JAVA] 자바 메서드 심화: 오버로딩과 오버라이딩  (0) 2024.07.19
[JAVA] 자바 함수(메서드)의 기초: 선언부터 사용까지  (1) 2024.07.19
[JAVA] 소켓 프로그래밍 3번  (1) 2024.07.08
[JAVA] 소켓 프로그래밍 2번  (1) 2024.07.08
[JAVA] 소켓 프로그래밍 1번  (0) 2024.07.08
'자바' 카테고리의 다른 글
  • [JAVA] 자바 메서드 심화: 오버로딩과 오버라이딩
  • [JAVA] 자바 함수(메서드)의 기초: 선언부터 사용까지
  • [JAVA] 소켓 프로그래밍 3번
  • [JAVA] 소켓 프로그래밍 2번
뚤떡이
뚤떡이
프로그래밍을 알아가며 저와 함께 성장하는 블로그 입니다
  • 뚤떡이
    뚤떡이의 발개벗긴개발
    뚤떡이
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • Docker (2)
      • 자바 (29)
        • start (10)
        • calcu (4)
        • process (7)
      • 플러터 (1)
      • 알고리즘 (12)
        • 개념 (2)
        • 구현 (5)
        • 백준 (0)
        • 프로그래머스 (5)
      • 이클립스 (4)
        • 초기설정 (4)
      • SQL (5)
      • IT 잡동사니 (10)
      • 개발 관련 (10)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    크롬 원격 데스크톱
    #python #개발일지 #번역 #메모리최적화 #websocket #redis #비동기프로그래밍
    GLPI
    MAC 크롬 원격
    synology
    #electron
    #자동화
    #개발일지
    시놀로지
    요구사항 정의서
    #번역
    스팸메일 #메일보안 #gophish #it보안 #오픈소스
    #프로젝트
    IT자산관리
    개발일지 #프로젝트후기 #gpt4 #번역 #자동화 #python #electron
    크롬 원격
    #apachesuperset #시놀로지 #db2 #데이터시각화 #기술블로그
    윈도우 크롬 원격
    #python
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
뚤떡이
[API] Python API와 Java 클라이언트를 이용한 CPK 분석 및 히스토그램 생성
상단으로

티스토리툴바