Новосибирский Государственный Университет
Опубликован: 20.08.2013 | Доступ: свободный | Студентов: 858 / 36 | Длительность: 14:11:00
Самостоятельная работа 2:

Базовые операции обработки изображений

6. Приложения

6.1. Приложение А. Исходный код основной функции консольного редактора изображений

#include <stdio.h> 
#include <opencv2/opencv.hpp> 
#include "functions.h" 
 
using namespace cv; 
 
const int kMenuTabs = 12; 
const char* menu[] = 
{ 
  "0 - Read image", 
  "1 - Apply linear filter", 
  "2 - Apply blur(...)", 
  "3 - Apply medianBlur(...)", 
  "4 - Apply GaussianBlur(...)", 
  "5 - Apply erode(...)", 
  "6 - Apply dilate(...)", 
  "7 - Apply Sobel(...)", 
  "8 - Apply Laplacian(...)", 
  "9 - Apply Canny(...)", 
  "10 - Apply calcHist(...)", 
  "11 - Apply equalizeHist(...)" 
}; 
const char* winNames[] = 
{ 
  "Initial image", 
  "filter2d", 
  "blur", 
  "medianBlur", 
  "GaussianBlur", 
  "erode", 
  "dilate", 
  "Sobel", 
  "Laplacian", 
  "Canny", 
  "calcHist", 
  "equalizeHist" 
}; 
const int maxFileNameLen = 1000; 
const int escCode = 27; 
 
void printMenu(); 
void chooseMenuTab(int &activeMenuTab, Mat &srcImg); 
void loadImage(Mat &srcImg); 
 
int main(int argc, char** argv) 
{ 
  Mat srcImg; // исходное изображение 
  char ans; 
  int activeMenuTab = -1; 
  do 
  {   
    // choose menu item 
    chooseMenuTab(activeMenuTab, srcImg); 
    // apply operation 
    applyOperation(srcImg, activeMenuTab); 
    // ask a question 
    printf("Do you want to continue? ESC - exit\n"); 
    // waiting for key will be pressed 
    ans = waitKey(); 
  } 
  while (ans != escCode); 
  destroyAllWindows(); // destroy all windows 
  // release memory allocated for storing image 
  srcImg.release(); 
  return 0; 
} 
 
void printMenu() 
{ 
  int i = 0; 
  printf("Menu items:\n"); 
  for (i; i < kMenuTabs; i++) 
  { 
    printf("\t%s\n", menu[i]); 
  } 
  printf("\n"); 
} 
 
void loadImage(Mat &srcImg) 
{ 
  char fileName[maxFileNameLen]; 
  do 
  { 
    printf("Input full file name: "); 
    scanf("%s", &fileName); 
    srcImg = imread(fileName, 1); 
  } 
  while (srcImg.data == 0); 
  printf("The image was succesfully read\n\n"); 
} 
 
void chooseMenuTab(int &activeMenuTab, Mat &srcImg) 
{ 
  int tabIdx; 
  while (true) 
  { 
    // print menu items 
    printMenu(); 
    // get menu item identifier to apply operation 
    printf( 
      "Input item identifier to apply operation: "); 
    scanf("%d", &tabIdx); 
    if (tabIdx == 0) 
    { 
      // read image 
      loadImage(srcImg); 
 } 
    else if (tabIdx >=1 && tabIdx < kMenuTabs && 
        srcImg.data == 0) 
    { 
      // read image 
      printf("The image should be read\ 
        to apply operation!\n"); 
      loadImage(srcImg); 
    } 
    else if (tabIdx >=1 && tabIdx < kMenuTabs) 
    { 
      activeMenuTab = tabIdx; 
      break; 
    } 
  } 
}       
    

6.2. Приложение Б. Исходный код заголовочного файла функционального модуля консольного редактора изображений

#ifndef __FUNCTIONS_H__ 
#define __FUNCTIONS_H__ 
 
#include <opencv2/opencv.hpp> 
 
using namespace cv; 
 
extern const int kMenuTabs; 
extern const char* winNames[]; 
 
// TODO: добавить прототипы функций, реализующих 
// другие операции 
int applyMedianBlur(const Mat &src, Mat &dst); 
 
int applyOperation(const Mat &src, const int operationIdx); 
 
#endif 
    

6.3. Приложение В. Исходный код функционального модуля консольного редактора изображений

#include "functions.h" 
 
int applyMedianBlur(const Mat &src, Mat &dst) 
{ 
  int kSize = 3, minDim = -1; 
  minDim = min(src.size().height, src.size().width); 
  do 
  { 
    printf("Set kernel size (odd, > 3, \ 
      < min(img.width, img.height)): "); 
    scanf("%d", &kSize); 
  } 
  while (kSize < 3 && kSize > minDim && kSize %2 == 0); 
  medianBlur(src, dst, kSize); 
  return 0; 
} 
 
int applyOperation(const Mat &src, const int operationIdx) 
{ 
  char key = -1; 
  Mat dst; 
  switch (operationIdx) 
  { 
  case 1: 
    { 
      // TODO: "1 - Apply linear filter" 
      break; 
    } 
  case 2: 
    { 
      // TODO: "2 - Apply blur(...)" 
      break; 
    } 
  case 3: 
    { 
      // "3 - Apply medianBlur(...)" 
      applyMedianBlur(src, dst); 
      break; 
    } 
  case 4: 
    { 
      // TODO: "4 - Apply GaussianBlur(...)" 
      break; 
    } 
  case 5: 
    { 
      // TODO: "5 - Apply erode(...)" 
      break; 
    } 
  case 6: 
    { 
      // TODO: "6 - Apply dilate(...)" 
      break; 
    } 
  case 7: 
    { 
      // TODO: "7 - Apply Sobel(...)" 
      break; 
    } 
  case 8: 
    { 
      // TODO: "8 - Apply Laplacian(...)" 
      break; 
    } 
  case 9: 
    { 
      // TODO: "9 - Apply Canny(...)" 
      break; 
    } 
  case 10: 
    { 
      // TODO: "10 - Apply calcHist(...)" 
      break; 
    } 
  case 11: 
    { 
      // TODO: "11 - Apply equalizeHist(...)" 
      break; 
    } 
  } 
  // show initial image 
  namedWindow(winNames[0], 1); 
  imshow(winNames[0], src); 
 
  // show processed image 
  namedWindow(winNames[operationIdx]); 
  imshow(winNames[operationIdx], dst); 
  return 0; 
}       
    
Александра Максимова
Александра Максимова

При прохождении теста 1 в нем оказались вопросы, который во-первых в 1 лекции не рассматривались, во-вторых, оказалось, что вопрос был рассмаотрен в самостоятельно работе №2. Это значит, что их нужно выполнить перед прохождением теста? или это ошибка?
 

Алена Борисова
Алена Борисова

В лекции по обработке полутоновых изображений (http://www.intuit.ru/studies/courses/10621/1105/lecture/17979?page=2) увидела следующий фильтр:


    \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 2 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array} - \frac{1}{9} \begin{array}{|c|c|c|}
    \hline \\
    0 & 0 & 0 \\
    \hline \\
    0 & 1 & 0 \\
    \hline \\
    0 & 0 & 0 \\
    \hline 
    \end{array}

В описании говорится, что он "делает изображение более чётким, потому что, как видно из конструкции фильтра, в однородных частях изображение не изменяется, а в местах изменения яркости это изменение усиливается".

Что вижу я в конструкции фильтра (скорее всего ошибочно): F(x, y) = 2 * I(x, y) - 1/9 I(x, y) = 17/9 * I(x, y), где F(x, y) - яркость отфильтрованного пикселя, а I(x, y) - яркость исходного пикселя с координатами (x, y). Что означает обычное повышение яркости изображения, при этом без учета соседних пикселей (так как их множители равны 0).

Объясните, пожалуйста, как данный фильтр может повышать четкость изображения?