#c #image-processing
#c #обработка изображений
Вопрос:
Как приведенный ниже код на самом деле удаляет шум из изображения? Я пытаюсь понять, что происходит, но, похоже, не могу уловить общую идею. Я пробовал это, и это работает (но не очень хорошо). Пожалуйста, дайте приблизительное объяснение. Спасибо.
void averageFilter(PIXEL_ARRAY* img, PIXEL_ARRAY* orig_img, int N)
{
int i, j, n, m;
int red_avg, blue_avg, green_avg;
int radius, out_of_bounds, idx, curr_idx;
int32_t pixel;
if (N % 2 == 0) {
printf("ERROR: Please use an odd sized windown");
exit(1);
}
radius = N / 2;
for (i = 0; i < img->sizeY; i ) {
for (j = 0; j < img->sizeX; j ) {
out_of_bounds = 0;
red_avg = 0;
blue_avg = 0;
green_avg = 0;
for (n = i - radius; n <= i radius; n ) {
for (m = j - radius; m <= j radius; m ) {
if (n < 0 || m < 0 || n >= img->sizeY || m >= img->sizeX) {
out_of_bounds ;
continue;
}
idx = m n * img->sizeX;
/* Shift, mask and add */
red_avg = ((orig_img->data[idx] >> 16) amp; 0xFF);
green_avg = ((orig_img->data[idx] >> 8) amp; 0xFF);
blue_avg = (orig_img->data[idx] amp; 0xFF);
}
}
/* Divide the total sum by the amount of pixels in the window */
red_avg /= (N * N - out_of_bounds);
green_avg /= (N * N - out_of_bounds);
blue_avg /= (N * N - out_of_bounds);
/* Set the average to the current pixel */
curr_idx = j i * img->sizeX;
pixel = (red_avg << 16) (green_avg << 8) blue_avg;
img->data[curr_idx] = pixel;
}
}
}
Ответ №1:
for (i = 0; i < img->sizeY; i ) {
for (j = 0; j < img->sizeX; j ) {`
Для всех пикселей в сетке…
for (n = i - radius; n <= i radius; n ) {
for (m = j - radius; m <= j radius; m ) {
Посетите местоположения в пределах radius
нашего пикселя…
if (n < 0 || m < 0 || n >= img->sizeY || m >= img->sizeX) {
out_of_bounds ;
continue;
(и помните, сколько мы нашли)
idx = m n * img->sizeX;
Когда мы находим местоположение, мы
n
пиксели вверх (основной пиксель-Y /-радиус),-
m
пиксели по горизонтали (main-pixel-X /- radius), так что… -
n
строки размером в пиксели, - плюс
m
для этой строки равен…
idx
: индекс пикселя нашего местоположения
red_avg = ((orig_img->data[idx] >> 16) amp; 0xFF);
green_avg = ((orig_img->data[idx] >> 8) amp; 0xFF);
blue_avg = (orig_img->data[idx] amp; 0xFF);
Подсчитайте данные RGB исходного изображения из каждого места, которое мы посещаем
/* Divide the total sum by the amount of pixels in the window */
red_avg /= (N * N - out_of_bounds);
green_avg /= (N * N - out_of_bounds);
blue_avg /= (N * N - out_of_bounds);
/* Set the average to the current pixel */
…усредните все местоположения в пределах radius
каждого основного пикселя…
curr_idx = j i * img->sizeX;
pixel = (red_avg << 16) (green_avg << 8) blue_avg;
img->data[curr_idx] = pixel;
…и установите main-pixel-index в выходном файле на среднее значение.
Ответ №2:
Код исследует окрестности каждого пикселя, находит среднее значение каждого компонента R, G, B и записывает их в выходное изображение. Итак, это сглаживающий фильтр. Я прокомментировал код:
void averageFilter(PIXEL_ARRAY* img, PIXEL_ARRAY* orig_img, int N)
{
int i, j, n, m;
int red_avg, blue_avg, green_avg;
int radius, out_of_bounds, idx, curr_idx;
int32_t pixel;
if (N % 2 == 0) {
printf("ERROR: Please use an odd sized windown");
exit(1);
}
radius = N / 2; // distance from pixel to explore
for (i = 0; i < img->sizeY; i ) { // parse each image pixel
for (j = 0; j < img->sizeX; j ) {
out_of_bounds = 0;
red_avg = 0; // init the averages
blue_avg = 0;
green_avg = 0;
for (n = i - radius; n <= i radius; n ) { // within the area to explore
for (m = j - radius; m <= j radius; m ) {
if (n < 0 || m < 0 || n >= img->sizeY || m >= img->sizeX) { // off the map?
out_of_bounds ; // count pixels off the map
continue; // and skip the summing
}
idx = m n * img->sizeX; // locate index of the pixel in source 1D array
/* Shift, mask and add */
red_avg = ((orig_img->data[idx] >> 16) amp; 0xFF); // extract each R,G,B in the region
green_avg = ((orig_img->data[idx] >> 8) amp; 0xFF); // and sum them
blue_avg = (orig_img->data[idx] amp; 0xFF);
}
}
/* Divide the total sum by the amount of pixels in the window */
red_avg /= (N * N - out_of_bounds); // produce an average R,G,B within the region
green_avg /= (N * N - out_of_bounds);
blue_avg /= (N * N - out_of_bounds);
/* Set the average to the current pixel */
curr_idx = j i * img->sizeX; // locate index in destination array
pixel = (red_avg << 16) (green_avg << 8) blue_avg; // merge the components
img->data[curr_idx] = pixel; // set its value to the average of the region
}
}
}