본문 바로가기

MATLAB/CropValidRegion

MATLAB Window example, CropValidRegion

MATLAB GUIDE 를 이용하여 Window 프로그램을 작성한 예

X-RAY 영상을 저장한 JPG 파일의 유효한 영상부분만을 잘라내어 별도의 JPG 파일에 저장한다

MATLAB 의 Command Window 의 명령행에서 mcc -m CropValidRegion.m<enter>를 실행하여 윈도우 실행파일(*.exe)으로 컴파일함

생성된 *.exe 파일은 실행될 시스템에 복사하고, 그 시스템에는 MCR(Matlab Compiler Runtime)이 설치되어 있어야 하는데, Matlab 사이트에서 MCRInstaller.exe 파일을 다운로드하여 실행하면 MCR이 설치된다. MCR이 설치된 후에 작성된 *.exe 파일을 실행하면 된다.

http://www.mathworks.co.kr/products/compiler/

http://www.mathworks.co.kr/products/compiler/mcr/index.html

 

CropValidRegion.exe

CropValidRegion.fig

CropValidRegion.m


% 이 프로그램은 MATLAB R2012a에서 작성되었으며 MATLAB 용어로 M 파일이므로 MATLAB안에 M파일로 저장하여 % 필요시에는 MATLAB의 Command Window에서 아래와 같이 호출하여 실행할 수 있다. % >> CropValidRegion() % 다른 컴퓨터에서 실행하려면 이 파일을 컴파일하여 *.exe 파일을 생성하면 되는데, MATLAB의 mcc 컴파일러 % 를 사용하면 된다. MATLAB의 Command Window에서 다음과 같이 명령하면 *.m 파일은 *.exe 파일로 컴파일된다. % >> mcc -m [ M 파일 이름 ]<enter> % >> mcc -m CropValidRegion.m<enter> function varargout = CropValidRegion(varargin) % CROPVALIDREGION MATLAB code for CropValidRegion.fig % CROPVALIDREGION, by itself, creates a new CROPVALIDREGION or raises the existing % singleton*. % % H = CROPVALIDREGION returns the handle to a new CROPVALIDREGION or the handle to % the existing singleton*. % % CROPVALIDREGION('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in CROPVALIDREGION.M with the given input arguments. % % CROPVALIDREGION('Property','Value',...) creates a new CROPVALIDREGION or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before CropValidRegion_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to CropValidRegion_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help CropValidRegion % Last Modified by GUIDE v2.5 27-Dec-2012 21:18:20 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @CropValidRegion_OpeningFcn, ... 'gui_OutputFcn', @CropValidRegion_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before CropValidRegion is made visible. function CropValidRegion_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to CropValidRegion (see VARARGIN) % Choose default command line output for CropValidRegion handles.output = hObject; % Update handles structure guidata(hObject, handles); % UIWAIT makes CropValidRegion wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = CropValidRegion_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % -------------------------------------------------------------------- function menuFile_Callback(hObject, eventdata, handles) % hObject handle to menuFile (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % -------------------------------------------------------------------- function menuClose_Callback(hObject, eventdata, handles) % hObject handle to menuClose (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) exit(); % --- Executes on selection change in fileListBox. function fileListBox_Callback(hObject, eventdata, handles) % hObject handle to fileListBox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: contents = cellstr(get(hObject,'String')) returns fileListBox contents as cell array % contents{get(hObject,'Value')} returns selected item from fileListBox % --- Executes during object creation, after setting all properties. function fileListBox_CreateFcn(hObject, eventdata, handles) % hObject handle to fileListBox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: listbox controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % -------------------------------------------------------------------- function toolOpen_ClickedCallback(hObject, eventdata, handles) % hObject handle to toolOpen (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) dname = uigetdir('C:\'); path = sprintf('%s\\*.jpg',dname); file_struct_arr = dir(path); len = length(file_struct_arr); set(handles.labelTotalFiles, 'String', len); %for i=1:len % disp(file_struct_arr(i).name) %end; % 왼쪽 ListBox에 소스 JPG 파일의 목록을 출력한다 % set(lbh,'Value',2) % 리스트 2번 아이템을 선택한 효과를 낸다 %[sorted_names,sorted_index] = sortrows({file_struct_arr.name}'); %handles.file_names = sorted_names; handles.file_names = {file_struct_arr.name} %handles.sorted_index = sorted_index; set(handles.fileListBox,'String',handles.file_names,'Value',1) set(handles.sourceDir,'String',dname) % 오른쪽 ListBox에 기본으로 존재하는 아이템을 제거한다 currentItems = get(handles.listCropped, 'String'); %disp(sprintf('%s:%d', '아이템수',length(currentItems))); newItems = currentItems; newItems(1) = []; set(handles.listCropped, 'String', newItems); % 현재파일의 하단에 있는 함수 호출, 유효영역만을 잘라내어 별도의 파일에 저장한다 crop(dname, handles); % waitbar를 이용하는 방법은 아래의 주석을 참조하세요 %h = waitbar(0,'Processing Rate'); %steps = 1000; %for step = 1:steps % computations take place here % waitbar(step / steps) %end %pause(1); %close(h) % -------------------------------------------------------------------- function menuHelp_Callback(hObject, eventdata, handles) % hObject handle to menuHelp (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) helpdlg('CropValidRegion v1.0, Contact: cwiskykim@gmail.com'); % --- Executes on selection change in listCropped. function listCropped_Callback(hObject, eventdata, handles) % hObject handle to listCropped (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: contents = cellstr(get(hObject,'String')) returns listCropped contents as cell array % contents{get(hObject,'Value')} returns selected item from listCropped % --- Executes during object creation, after setting all properties. function listCropped_CreateFcn(hObject, eventdata, handles) % hObject handle to listCropped (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: listbox controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on slider movement. function slider_Callback(hObject, eventdata, handles) % hObject handle to slider (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider slider_value = num2str(get(hObject, 'Value')); % disp(sprintf('슬라이더 값:%s', slider_value)); set(handles.labelThreshold,'String', slider_value); % --- Executes during object creation, after setting all properties. function slider_CreateFcn(hObject, eventdata, handles) % hObject handle to slider (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % 이 프로그램은 MATLAB R2012a에서 작성되었으며 MATLAB 용어로 M 파일이므로 MATLAB안에 M파일로 저장하여 % 필요시에는 MATLAB의 Command Window에서 아래와 같이 호출하여 실행할 수 있다. % >> CropValidRegion(); % 다른 컴퓨터에서 실행하려면 이 파일을 컴파일하여 *.exe 파일을 생성하면 되는데, MATLAB의 mcc 컴파일러 % 를 사용하면 된다. MATLAB의 Command Window에서 다음과 같이 명령하면 *.m 파일은 *.exe 파일로 컴파일된다. % >> mcc -m [ M 파일 이름 ]<enter> % >> mcc -m CropValidArea.m<enter> function b = crop(dname, handles) % 촬영된 이미지의 유효영역이 일정한 영역에 위치한다면 아래의 변수를 사용하여 루프를 실행할 때 % 루프의 횟수를 단축할 수 있도록 유효영역에 근접하게 아래의 변수를 설정하고 루프에서 사용하면 된다 xStart = 0; yStart = 0; xEnd = 0; yEnd = 0; % 파일열기 대화창을 이용하여 이용자로부터 대상 디렉토리를 선택할 수 있게 한다 % 선택한 디렉토리 안에 있는 모든 jpg 파일들을 대상으로 로직을 실행한다 %dname = uigetdir('C:\'); % 파일열기 대화창을 보여주고 선택된 디렉토리 경로를 리턴한다 src_path = sprintf('%s/*.jpg', dname); % 소스 경로 dst_path = sprintf('%s/crop',dname); % 유효영역을 잘라내어 저장할 경로 err_path = sprintf('%s/err', dname); % 처리 중 오류로 인하여 처리하지 못한 파일이 저장되는 경로 num = exist(dst_path, 'dir'); if num ~= 7 mkdir(dst_path); % 소스 디렉토리 안에 저장용 디렉토리 생성 end; num = exist(err_path, 'dir'); if num ~= 7 mkdir(err_path); % 소스 디렉토리 안에 에러발생 파일 저장용 디렉토리 생성 end; file_struct_arr = dir(src_path); % 소스 디렉토리 안의 모든 jpg 파일 리스트를 구조체 배열로 리턴함 h = waitbar(0,'Processing Rate'); % 진행량을 표시할 콘트롤 생성 len = length(file_struct_arr); for i=1:len % 모든 이미지를 로드하고 유효영역을 검사 및 잘라내서 crop 디렉토리에 저장한다 try % 특정 파일을 처리하는 중에 오류가 발생하면 해당 파일을 err 디렉토리에 복사하려는 의도 rgbImg = imread( sprintf('%s/%s', dname, file_struct_arr(i).name)); grImg = rgb2gray(rgbImg); % 색상대조와 밝기를 조정하는 방법 %newImage = imadjust(originalImage, [a b], [c d]); %Where variables a, b, c and d are between 0 and 1. %To decrease contrast: increase a %To increase contrast: decrease b %To increase brightness: increase c %To decrease brightness: decrease d %Here is full example increasing contrast by 20% %contrastImage = imadjust(originalImage, [0 0.8], [0 1]); slider_value = get(handles.slider,'Value'); grImg2 = imadjust(grImg,[0 slider_value],[0 1]); % 테스트 결과 0.79가 최적 binImg = im2bw(grImg2, slider_value); % 흑백 영상으로 변환 % 새뷰박스 파라미터 설정 테스트 결과 % 0.4 : 처리 중 일부 파일에서 오류발생, 원인은 유효한 영역이 식별되지 않았기 때문임 % 0.70: 유효한 영역이 잘려나가는 파일이 약간 있음 % 0.72: 유효한 영역이 온전히 유지됨 % 0.80: 무효한 영역이 잘리지 않기 시작함 % 파라미터 설정 테스트 결과 끝 %imshow(binImg); % 이진화 이미지 출력 sz = size(binImg); %disp(sz); h = sz(1); % 행수 w = sz(2); % 열수 msg = sprintf('폭=%d, 높이=%d',w,h); %disp(msg); left=0; right = 0; top = 0; bottom = 0; sum = 0; % 이미지에서 검은색이 시작되는 좌측끝 좌표를 찾는다(왼쪽에서 오른쪽으로 수직선상의 검은 점을 검사함) go = 1; for x=1:w sum = 0; if(go==0) break; end; for y=1:h if(binImg(y,x)==0) %한개의 수직선 상에 검은 픽셀이 연속하여 50개 이상인 경우 유효한 영역의 시작점으로 간주한다 sum = sum + 1; %disp(sprintf('발견(L), x=%d, y=%d',x,y)); if(sum>50) left = x; go = 0; break; end; else sum = 0; end; end; end; % 이미지에서 검은색이 시작되는 우측끝 좌표를 찾는다(오른쪽에서 왼쪽으로 검사함) go = 1; for x=w:-1:1 sum = 0; if(go==0) break; end; for y=1:h if(binImg(y,x)==0) %disp(sprintf('발견(R), x=%d, y=%d',x,y)); %한개의 수평선 상에 검은 픽셀이 연속하여 50개 이상인 경우 유효한 영역의 시작점으로 간주한다 sum = sum + 1; if(sum>50) right = x; go = 0; break; end; else sum = 0; end; end; end; % 이미지에서 검은색이 시작되는 상단 좌표를 찾는다(위에서 아래쪽으로 검사함) go = 1; for y=1:h sum = 0; if(go==0) break; end; for x=1:w if(binImg(y,x)==0) %disp(sprintf('발견(T), x=%d, y=%d',x,y)); sum = sum + 1; if(sum>50) top = y; go = 0; break; end; else sum = 0; end; end; end; % 이미지에서 검은색이 시작되는 하단 좌표를 찾는다(아래쪽에서 위쪽으로 검사함) go = 1; for y=h:-1:1 sum = 0; if(go==0) break; end; for x=1:w if(binImg(y,x)==0) %disp(sprintf('발견(B), x=%d, y=%d',x,y)); sum = sum + 1; if(sum>50) bottom = y; go = 0; break; end; else sum = 0; end; end; end; %disp(sprintf('유효한 이미지 영역= %d, %d, %d, %d', left, top, right, bottom)) cropImg = imcrop(grImg, [left,top,right-left,bottom-top]); %imshow(cropImg); dst_file = sprintf('%s/%s', dst_path, file_struct_arr(i).name); imwrite(cropImg, dst_file,'jpg'); oldstring = get(handles.listCropped, 'String'); if isempty(oldstring) newstring = file_struct_arr(i).name; elseif ~iscell(oldstring) newstring = {oldstring file_struct_arr(i).name}; else newstring = {oldstring{:} file_struct_arr(i).name}; end; catch src_file = sprintf('%s/%s', dname, file_struct_arr(i).name); err_file = sprintf('%s/%s', err_path, file_struct_arr(i).name); copyfile(src_file, err_file) end; % End of try catch block set(handles.listCropped,'String', newstring); set(handles.labelProcessed, 'String', i); set(handles.labelProcessingRate, 'String', i/len*100); waitbar(i/len); end; % End of for loop