Опубликован: 20.08.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Новосибирский Государственный Университет
Самостоятельная работа 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).

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

Сергей Кротов
Сергей Кротов
Россия
Дмитрий Донсков
Дмитрий Донсков
Россия, Москва, Московский Авиационный Институт