앞선 글에서 그나마 노트북 좋은 거를 장만해서 카메라가 달려 있다는 것(?)을 발견 하는 좋은 기회가 되었다는 것을 인정 할 수 밖에 없네요...
정말 처음에 시작 할 때는 내가 이미지 프로세싱이라는 것이 뭔지 모두 알아내 주마 하고 시작 했었던 때가 있었습니다. (글을 찾아 보니 2017년 정도네요..)
지금 생각해 보는 것이지만...
그게 뭔지 열심히 공부 하지 않을 것이라면 깊이 알 필요 없다 라는 것으로 결론이 났습니다.
뭐 아는 것도 잊어 먹는 판국에 ♪(๑ᴖ◡ᴖ๑)♪ ~~
오늘은 카메라가 노트북에 달려 있다는 것을 알았으니...
프로세싱에 도전을 해 볼 생각입니다. 물론 많이 도전 했었죠.. 이번에는 자바로 말이죠.
잘 모르니 그냥 어떤 분 소스를 퍼다가 내가 맘대로 하기로 했습니다.
github 에서 받아다 썼는 데... 어딘지 모르겠네요~
여하튼 소스는 어차피 맘대로 고쳤으니, 혹시 위치를 알게 되면 업데이트 하기로 하겠습니다.
UI 는 이렇게 구성 할 겁니다. 기존 UI 옆에다가 버튼을 갖다가 붙일 거예요
이렇게( ◜𖥦◝ )
왼쪽에다가 Panel 을 하다 붙여야 겠죠...
이렇게~♪(๑ᴖ◡ᴖ๑)♪ - 영어로는 WEST 네요...
private void initCamPanel(final boolean isCanvas)
{
JPanel btnPane = new ButtonPanel();
if(!isCanvas)
{
camPane.setSize(new Dimension(600, 450));
camPane.setPreferredSize(new Dimension(600, 450));
setLayout(new BorderLayout());
add(camPane, BorderLayout.CENTER);
add(goCam, BorderLayout.SOUTH);
add(btnPane, BorderLayout.WEST); // 이렇게 ( ◜𖥦◝ )
goCam.setActionCommand("goCamPanel");
goCam.addActionListener(btnListener);
}
else
{
... 생략 ...
}
}
ButtonPanel 은 귀찮으니까 내부에다 만들겁니다.
그래야 소스는 뭐 복잡해 지겠지만, 클래스 변수들을 갖다 쓰는 것도 편하고, 카메라도 접근하기 편하기도 해서 그냥 쓸거예요
final class ButtonPanel extends JPanel {
private static final long serialVersionUID = 1101056225940013101L;
ButtonPanel()
{
setLayout(new GridLayout(4,0));
setSize(new Dimension(100, 450));
setPreferredSize(new Dimension(100, 450));
initButtonPane();
}
void initButtonPane()
{
JButton btnRGB = new JButton("RGB");
btnRGB.setActionCommand("ConvBGR");
JButton btnGrayscal = new JButton("Gray scale");
btnGrayscal.setActionCommand("ConvGray");
JButton btnBlackWhite = new JButton("Black&White");
btnBlackWhite.setActionCommand("ConvBlackWhite");
JButton btnCanny = new JButton("Canny");
btnCanny.setActionCommand("ConvCanny");
//Add controls to set up horizontal and vertical gaps
add(btnRGB);
add(btnGrayscal);
add(btnBlackWhite);
add(btnCanny);
btnRGB.addActionListener(btnFuncListener);
btnGrayscal.addActionListener(btnFuncListener);
btnBlackWhite.addActionListener(btnFuncListener);
btnCanny.addActionListener(btnFuncListener);
}
}
액션리스너를 하나 선언(btnFuncListener)하고 각 버튼마다 이름을 붙혔습니다(setActionCommand).
액션 리스너는... 이렇게 이렇게~♪(๑ᴖ◡ᴖ๑)♪
class FunctionButtonClickListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("ConvGray")) {
startCam(mIsCanvasDrawing, GRAY_SCALE_DRAWING);
} else if (e.getActionCommand().equals("ConvCanny")) {
startCam(mIsCanvasDrawing, CANNY_DRAWING);
}else if (e.getActionCommand().equals("ConvBlackWhite")) {
startCam(mIsCanvasDrawing, BLACK_AND_WHITE_DRAWING);
} else if (e.getActionCommand().equals("ConvBGR")) {
startCam(mIsCanvasDrawing, RGBA_DRAWING);
}
}
}
잘 만들었네요~(😮ㅋㅋ)
GUI 만들 때, 원래는 하단에 go Cam 버튼 하나만 있었기 때문에, 시작 하고 난 후에는 버튼 명을 stop 으로 만들고 stop 버튼을 누르면 모든 게 종료 되는 모양새 였습니다.
하단 버튼의 액션에 대한 종료 는 다음과 같이 일어 나게 됩니다.
1. 타이머가 종료 되었는가?
1.1 예 > 카메라를 끈다.
1.2 아니오 > 타이머를 종료 한다 > 카메라를 끈다.
였습니다.
왼쪽 버튼들의 액션은 이렇게 생각 해 보았죠.
- 타이머가 종료 되었는가?
- 예 > 버튼 액션을 진행 한다.
- 아니요 > 타이머를 종료 한다 > 버튼 액션을 진행 한다.
입니다.
그럼, 타이머는 무슨 동작을 할까요?
- 카메라가 켜져 있는가?
- 예 > 프레임을 읽어 들인다.
- 아니오 > 오류를 출력 한다.
입니다.
대충 내용이 끝난네요..그럼 startCam 메서드를 한 번 만들어 보았습니다.
이렇게~♪(๑ᴖ◡ᴖ๑)♪ - 말로 한게 아닌데 입이 아프네요.
protected void startCam(final boolean isCanvas, final int functionId) {
InnerUtil.stopTimer();
if(mIsCanvasDrawing)
{
camCavs.startCamera(functionId);
}
else
{
camPane.startCamera(functionId);
}
}
startCamera 메서드가 바꼈네요.. 정확히는 바뀐게 아니라 오버로딩 되었습니다(overloading)
하나 더 생겼다는 말이죠...이렇게~♪(๑ᴖ◡ᴖ๑)♪
protected void startCamera(int drawingStyle) {
if (this.cameraActive) {
// is the video stream available?
if (InnerUtil.isCamOpened()) {
cameraActive = true;
// grab a frame every 33 ms (30 frames/sec)
Runnable frameGrabber = new Runnable() {
@Override
public void run() {
// effectively grab and process a single frame
Mat frame = InnerUtil.grabFrame(drawingStyle);
// convert and show the frame
bufImagew = Utils.matToBufferedImage(frame);
//System.out.println("3 " + bufImagew.getWidth() + ":" + bufImagew.getWidth());
// updateImageView(currentFrame, imageToShow);
repaint();
// invalidate();
}
};
InnerUtil.scheduleStart(frameGrabber);
// update the button content
goCam.setText("Stop Camera");
} else {
// log the error
System.err.println("Impossible to open the camera connection...");
}
} else {
// the camera is not active at this point
this.cameraActive = false;
// update again the button content
goCam.setText("Start Camera");
// stop the timer
InnerUtil.stopAcquisition();
}
}
}
하나 더 있는 startCamera 메서드는 저번 글에서 확인 하시면 됩니다.
그리고 cameraActive 변수가 꼭 있어야 하는 지는 모르겠습니다.
그냥 생각하고 싶지는 않은 걸로~
혹자는... 오버로딩이 객체지향 할 때 쓴다더군요. 궁금하시면 알아 보시길 바라며~^^
그리고 나면, 가장 중요한 메서드가 하나 나옵니다.
grabFrame 입니다. 이 놈도 오버로딩 되었습니다...
하나 더...이렇게~♪(๑ᴖ◡ᴖ๑)♪
static Mat grabFrame(int drawingStyle) {
// init everything
Mat frame = new Mat();
// check if the capture is open
if (capture.isOpened()) {
try {
// read the current frame
capture.read(frame);
// if the frame is not empty, process it
if (!frame.empty()) {
switch(drawingStyle)
{
case GRAY_SCALE_DRAWING:
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);
break;
case CANNY_DRAWING:
frame = CannyFunction.Canny(frame);
break;
case BLACK_AND_WHITE_DRAWING:
frame = CannyFunction.BlackAndWhite(frame, 3);
break;
case RGBA_DRAWING:
//Nothing to do...
}
}
} catch (Exception e) {
// log the error
System.err.println("Exception during the image elaboration: " + e);
}
}
return frame;
}
누구나 보듯이 젤 중요 하는 곳은 스위치 케이스 구문 이겠죠?
switch(drawingStyle)
{
case GRAY_SCALE_DRAWING:
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);
break;
case CANNY_DRAWING:
frame = CannyFunction.Canny(frame);
break;
case BLACK_AND_WHITE_DRAWING:
frame = CannyFunction.BlackAndWhite(frame, 3);
break;
case RGBA_DRAWING:
//Nothing to do...
}
Mat 오브젝트를 어떻게 다룰 것인가 라는 부분이 들어 있는 곳 입니다.
내 예상이 맞다면? 다음 같은 기능을 기대 해야 하겠죠?
첫번째 버튼 - 천연 색(?) 삼다수 - 카메라 화질이 영 별로네요...
두번 째 버튼 - 칙칙한 삼다수
세 번째 버튼: 조화로운 삼다수 - 근데 이건 뭔지 좀 더 알아봐야 할 듯 하네요...
위에 거와 같음...
음...
네 번째 버튼 : 캐니 삼다수 - 삼다수 글자가 보이시나요??
대충 결과물과 코드에 대해서 정리 해 보았습니다.
계속...
'프로그래밍 > [Java] OpenCV' 카테고리의 다른 글
OpenCV와 자바 - 4.1. 이미지 조작 - 1 (0) | 2022.09.14 |
---|---|
OpenCV와 자바 - 4. 동영상과 이미지 UI-1 (1) | 2022.09.13 |
OpenCV와 자바 - 3. 프로세싱-2 (0) | 2022.09.12 |
OpenCV와 자바 - 2. 헬로 Camera (0) | 2022.09.09 |
OpenCV와 자바 - 1. 헬로 OpenCV (3) | 2022.09.08 |