Language: C++ For this lab, you will do some basic manipulations of gray-scale i
ID: 3606246 • Letter: L
Question
Language: C++For this lab, you will do some basic manipulations of gray-scale images. The obvious data structure for an image is a 2-D array, so you will be writing functions that manipulate 2-D arrays. TASKS For all tasks:
There are many image formats (jpg, png, etc.), and we will use PGM (Portable GrayMap) since it is a simple grayscale format. You may need to use the following linux programs while developing your programs. Viewing a PGM image: eog and gimp are standard Linux program for viewing images in various formats. Converting between image formats: The Linux utility convert will convert between all standard formats, where its 2 arguments are the input and output files, with format determined by filename suffix. You won't need this unless you want to play with other image formats. We need a way to convert gray-scale images to arrays, and output arrays into image files. Your instructor will supply you two functions as follows: writeImage: writes the argument image (a 2-D array) to outImage.pgm in PGM grayscale format. readImage: reads a PGM grayscale format from inImage.pgm into an array, and updates the height/width arguments appropriately (since they are passed by reference). You may use these functions as is. Task 0:
First, we need a gray-scale image to work on. Save the one supplied by your instructor to $PWD. This file format has 8-bit images - i.e., each pixel is a gray scale value between 0 and 255 inclusive. Since all our tasks will involve reading an image file, processing the image, and writing the processed image back to a different file, we will first get the basics setup. Write a small program that uses the given readimage/writeimage functions to input the PPM file into an array, copies the image to a 2nd array, and writes the 2nd array back. View the resulting image to make sure its the same as the original image. Task 1:
One way to highlight objects in an image is to make all pixels below a threshold (t1) 0, and all pixels above a threshold (t2) 255. Write a function to highlight the image, using the following prototype: void highlight(int image[][MAXHEIGHT],int width, int height, int t1, int t2) Write a main program that inputs t1 and t2 from the user, highlights the image, and then writes the image.
This highlighting is called segmentation, though most segmentation algorithms are much more complicated. Task 2:
One way to pixelate an image is to effectively make every nXn non-overlapping window contain the same value (the obvious value is the average of the window). For example, if n=2, the following image: 10 20 30 40 11 21 31 41 12 22 32 42 13 23 33 43 may be transformed to: 16 16 36 36 16 16 36 36 18 18 37 37 18 18 37 37
Repeat the earlier tasks, except with a function named scale. Your function should work for arbitrary values of n, though you are free to simplify your work by defining arbitrary behaviors for the problematic values of n (I suggest you define such behaviors to be whatever falls out of your code). But make sure to state in comments how you handle any problematic values for n. Task 3:
A sliding window operator replaces each pixel with some function of its 8 neighbors (and itself). Consider the following 3X3 window: a b c d e f g h i Then, pixel e would be replaced by some function f(a,b,c,d,e,f,g,h,i). One way to detect horizontal edges is to use the function (g+2h+i)-(a+2b+c). Note that this is a sliding window operator unlike the non-overlapping windows in the previous task - that is, the window is always a window around the pixel whose value is being computed.
Write a horizontal edge detection function, named hEdgeDet. For the top/bottom rows and left/right columns of the image, you should assume a wrap-around - for example, if the image has width 64 and you are determining the value of the pixel at column 0 row 14, the d argument would be the pixel at column 63 row 14. Language: C++
For this lab, you will do some basic manipulations of gray-scale images. The obvious data structure for an image is a 2-D array, so you will be writing functions that manipulate 2-D arrays. TASKS For all tasks:
There are many image formats (jpg, png, etc.), and we will use PGM (Portable GrayMap) since it is a simple grayscale format. You may need to use the following linux programs while developing your programs. Viewing a PGM image: eog and gimp are standard Linux program for viewing images in various formats. Converting between image formats: The Linux utility convert will convert between all standard formats, where its 2 arguments are the input and output files, with format determined by filename suffix. You won't need this unless you want to play with other image formats. We need a way to convert gray-scale images to arrays, and output arrays into image files. Your instructor will supply you two functions as follows: writeImage: writes the argument image (a 2-D array) to outImage.pgm in PGM grayscale format. readImage: reads a PGM grayscale format from inImage.pgm into an array, and updates the height/width arguments appropriately (since they are passed by reference). You may use these functions as is. Task 0:
First, we need a gray-scale image to work on. Save the one supplied by your instructor to $PWD. This file format has 8-bit images - i.e., each pixel is a gray scale value between 0 and 255 inclusive. Since all our tasks will involve reading an image file, processing the image, and writing the processed image back to a different file, we will first get the basics setup. Write a small program that uses the given readimage/writeimage functions to input the PPM file into an array, copies the image to a 2nd array, and writes the 2nd array back. View the resulting image to make sure its the same as the original image. Task 1:
One way to highlight objects in an image is to make all pixels below a threshold (t1) 0, and all pixels above a threshold (t2) 255. Write a function to highlight the image, using the following prototype: void highlight(int image[][MAXHEIGHT],int width, int height, int t1, int t2) Write a main program that inputs t1 and t2 from the user, highlights the image, and then writes the image.
This highlighting is called segmentation, though most segmentation algorithms are much more complicated. Task 2:
One way to pixelate an image is to effectively make every nXn non-overlapping window contain the same value (the obvious value is the average of the window). For example, if n=2, the following image: 10 20 30 40 11 21 31 41 12 22 32 42 13 23 33 43 may be transformed to: 16 16 36 36 16 16 36 36 18 18 37 37 18 18 37 37
Repeat the earlier tasks, except with a function named scale. Your function should work for arbitrary values of n, though you are free to simplify your work by defining arbitrary behaviors for the problematic values of n (I suggest you define such behaviors to be whatever falls out of your code). But make sure to state in comments how you handle any problematic values for n. Task 3:
A sliding window operator replaces each pixel with some function of its 8 neighbors (and itself). Consider the following 3X3 window: a b c d e f g h i Then, pixel e would be replaced by some function f(a,b,c,d,e,f,g,h,i). One way to detect horizontal edges is to use the function (g+2h+i)-(a+2b+c). Note that this is a sliding window operator unlike the non-overlapping windows in the previous task - that is, the window is always a window around the pixel whose value is being computed.
Write a horizontal edge detection function, named hEdgeDet. For the top/bottom rows and left/right columns of the image, you should assume a wrap-around - for example, if the image has width 64 and you are determining the value of the pixel at column 0 row 14, the d argument would be the pixel at column 63 row 14.
For this lab, you will do some basic manipulations of gray-scale images. The obvious data structure for an image is a 2-D array, so you will be writing functions that manipulate 2-D arrays. TASKS For all tasks:
There are many image formats (jpg, png, etc.), and we will use PGM (Portable GrayMap) since it is a simple grayscale format. You may need to use the following linux programs while developing your programs. Viewing a PGM image: eog and gimp are standard Linux program for viewing images in various formats. Converting between image formats: The Linux utility convert will convert between all standard formats, where its 2 arguments are the input and output files, with format determined by filename suffix. You won't need this unless you want to play with other image formats. We need a way to convert gray-scale images to arrays, and output arrays into image files. Your instructor will supply you two functions as follows: writeImage: writes the argument image (a 2-D array) to outImage.pgm in PGM grayscale format. readImage: reads a PGM grayscale format from inImage.pgm into an array, and updates the height/width arguments appropriately (since they are passed by reference). You may use these functions as is. Task 0:
First, we need a gray-scale image to work on. Save the one supplied by your instructor to $PWD. This file format has 8-bit images - i.e., each pixel is a gray scale value between 0 and 255 inclusive. Since all our tasks will involve reading an image file, processing the image, and writing the processed image back to a different file, we will first get the basics setup. Write a small program that uses the given readimage/writeimage functions to input the PPM file into an array, copies the image to a 2nd array, and writes the 2nd array back. View the resulting image to make sure its the same as the original image. Task 1:
One way to highlight objects in an image is to make all pixels below a threshold (t1) 0, and all pixels above a threshold (t2) 255. Write a function to highlight the image, using the following prototype: void highlight(int image[][MAXHEIGHT],int width, int height, int t1, int t2) Write a main program that inputs t1 and t2 from the user, highlights the image, and then writes the image.
This highlighting is called segmentation, though most segmentation algorithms are much more complicated. Task 2:
One way to pixelate an image is to effectively make every nXn non-overlapping window contain the same value (the obvious value is the average of the window). For example, if n=2, the following image: 10 20 30 40 11 21 31 41 12 22 32 42 13 23 33 43 may be transformed to: 16 16 36 36 16 16 36 36 18 18 37 37 18 18 37 37
Repeat the earlier tasks, except with a function named scale. Your function should work for arbitrary values of n, though you are free to simplify your work by defining arbitrary behaviors for the problematic values of n (I suggest you define such behaviors to be whatever falls out of your code). But make sure to state in comments how you handle any problematic values for n. Task 3:
A sliding window operator replaces each pixel with some function of its 8 neighbors (and itself). Consider the following 3X3 window: a b c d e f g h i Then, pixel e would be replaced by some function f(a,b,c,d,e,f,g,h,i). One way to detect horizontal edges is to use the function (g+2h+i)-(a+2b+c). Note that this is a sliding window operator unlike the non-overlapping windows in the previous task - that is, the window is always a window around the pixel whose value is being computed.
Write a horizontal edge detection function, named hEdgeDet. For the top/bottom rows and left/right columns of the image, you should assume a wrap-around - for example, if the image has width 64 and you are determining the value of the pixel at column 0 row 14, the d argument would be the pixel at column 63 row 14. For this lab, you will do some basic manipulations of gray-scale images. The obvious data structure for an image is a 2-D array, so you will be writing functions that manipulate 2-D arrays. TASKS For all tasks:
There are many image formats (jpg, png, etc.), and we will use PGM (Portable GrayMap) since it is a simple grayscale format. You may need to use the following linux programs while developing your programs. Viewing a PGM image: eog and gimp are standard Linux program for viewing images in various formats. Converting between image formats: The Linux utility convert will convert between all standard formats, where its 2 arguments are the input and output files, with format determined by filename suffix. You won't need this unless you want to play with other image formats. We need a way to convert gray-scale images to arrays, and output arrays into image files. Your instructor will supply you two functions as follows: writeImage: writes the argument image (a 2-D array) to outImage.pgm in PGM grayscale format. readImage: reads a PGM grayscale format from inImage.pgm into an array, and updates the height/width arguments appropriately (since they are passed by reference). You may use these functions as is. Task 0:
First, we need a gray-scale image to work on. Save the one supplied by your instructor to $PWD. This file format has 8-bit images - i.e., each pixel is a gray scale value between 0 and 255 inclusive. Since all our tasks will involve reading an image file, processing the image, and writing the processed image back to a different file, we will first get the basics setup. Write a small program that uses the given readimage/writeimage functions to input the PPM file into an array, copies the image to a 2nd array, and writes the 2nd array back. View the resulting image to make sure its the same as the original image. Task 1:
One way to highlight objects in an image is to make all pixels below a threshold (t1) 0, and all pixels above a threshold (t2) 255. Write a function to highlight the image, using the following prototype: void highlight(int image[][MAXHEIGHT],int width, int height, int t1, int t2) Write a main program that inputs t1 and t2 from the user, highlights the image, and then writes the image.
This highlighting is called segmentation, though most segmentation algorithms are much more complicated. Task 2:
One way to pixelate an image is to effectively make every nXn non-overlapping window contain the same value (the obvious value is the average of the window). For example, if n=2, the following image: 10 20 30 40 11 21 31 41 12 22 32 42 13 23 33 43 may be transformed to: 16 16 36 36 16 16 36 36 18 18 37 37 18 18 37 37
Repeat the earlier tasks, except with a function named scale. Your function should work for arbitrary values of n, though you are free to simplify your work by defining arbitrary behaviors for the problematic values of n (I suggest you define such behaviors to be whatever falls out of your code). But make sure to state in comments how you handle any problematic values for n. Task 3:
A sliding window operator replaces each pixel with some function of its 8 neighbors (and itself). Consider the following 3X3 window: a b c d e f g h i Then, pixel e would be replaced by some function f(a,b,c,d,e,f,g,h,i). One way to detect horizontal edges is to use the function (g+2h+i)-(a+2b+c). Note that this is a sliding window operator unlike the non-overlapping windows in the previous task - that is, the window is always a window around the pixel whose value is being computed.
Write a horizontal edge detection function, named hEdgeDet. For the top/bottom rows and left/right columns of the image, you should assume a wrap-around - for example, if the image has width 64 and you are determining the value of the pixel at column 0 row 14, the d argument would be the pixel at column 63 row 14.
Explanation / Answer
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <math.h>
#include <stdlib.h> // rand
#include <time.h>
using namespace std;
const int MAXWIDTH = 512;
const int MAXHEIGHT = 512;
int image[MAXWIDTH][MAXHEIGHT]; // first image array
int imageSec[MAXWIDTH][MAXHEIGHT]; // second image array
void readImage(int image[][MAXHEIGHT], int &width, int &height);
void writeImage(int image[][MAXHEIGHT], int width, int height);
void highlight(int image[][MAXHEIGHT], int width, int height, int t1, int t2);
void quantize(int image[][MAXHEIGHT], int width, int height, int q);
void pixelate(int image[][MAXHEIGHT], int width, int height, int n);
void niceImage(int image[][MAXHEIGHT], int question, int width, int height);
void edgeDet(int image[][MAXHEIGHT], int width, int height);
int main()
{
int width = MAXWIDTH;
int height = MAXHEIGHT;
readImage(image, width, height);
for (int w = 0; w < MAXWIDTH; w++)
{
for (int h = 0; h < MAXHEIGHT; h++)
{
imageSec[w][h] = image[w][h];
}
}
writeImage(imageSec, width, height);
int t1, t2;
cout << " Task 1 Enter t1 threshold: ";
cin >> t1;
cout << "Enter t2 theshold: ";
cin >> t2;
highlight(image, width, height, t1, t2);
writeImage(image, width, height);
int q; // how many shades of colors we will have when quantizing
cout << " Task 2 Enter value for q: ";
cin >> q;
quantize(image, width, height, q);
writeImage(image, width, height);
int n;
cout << " Task 3 Enter a value for n: ";
cin >> n;
pixelate(image, width, height, n);
writeImage(image, width, height);
int cont; // to pause before continuing processing image with new function
cout << " Task 4 Enter any integer value to continue: ";
cin >> cont;
edgeDet(image, width, height);
writeImage(image, width, height);
int question = 1;
cout << " Task 5 Produce interesting image? (0 = yes) ";
cin >> question;
niceImage(image, question, width, height);
writeImage(image, width, height);
return 0;
}
void readImage(int image[][MAXHEIGHT], int &width, int &height) {
char c;
int x;
ifstream instr;
instr.open("inImage.pgm");
instr >> c; assert(c == 'P');
instr >> c; assert(c == '2');
while ((instr >> ws).peek() == '#') { instr.ignore(4096, ' '); }
instr >> width;
instr >> height;
assert(width <= MAXWIDTH);
assert(height <= MAXHEIGHT);
int max;
instr >> max;
assert(max == 255);
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
instr >> image[col][row];
instr.close();
return;
}
void writeImage(int image[][MAXHEIGHT], int width, int height) {
ofstream ostr;
ostr.open("outImage.pgm");
if (ostr.fail()) {
cout << "Unable to write file ";
exit(1);
};
ostr << "P2" << endl;
ostr << width << ' ';
ostr << height << endl;
ostr << 255 << endl;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
assert(image[col][row] < 256);
assert(image[col][row] >= 0);
ostr << image[col][row] << ' ';
// lines should be no longer than 70 characters
if ((col + 1) % 16 == 0) ostr << endl;
}
ostr << endl;
}
ostr.close();
return;
}
void highlight(int image[][MAXHEIGHT], int width, int height, int t1, int t2)
{
for (int w = 0; w < width; w++)
{
for (int h = 0; h < height; h++)
{
if (image[w][h] < t1)
{
image[w][h] = 0;
}
else if (image[w][h] > t2)
{
image[w][h] = 255;
}
}
}
return;
}
void quantize(int image[][MAXHEIGHT], int width, int height, int q)
{
int totalShades = 256;
vector<int> rangesMax(q);
vector<int> rangesMin(q);
int section = 256 / q;
rangesMax[0] = section - 1;
rangesMin[0] = 0;
for (int i = 1; i < q; i++)
{
// if q was odd, and on last range, then last range will be uneven
if ((q % 2 != 0) && (i = q - 1))
{
rangesMax[i] = rangesMax[i - 1] + (totalShades - 1 - rangesMax[i - 1]); //prev max + 255-prevmax
rangesMin[i] = rangesMin[i - 1] + section; // pre min + section
}
else {
rangesMax[i] = rangesMax[i - 1] + section; // prev max + section
rangesMin[i] = rangesMin[i - 1] + section; // pre min + section
}
}
for (int w = 0; w < width; w++)
{
for (int h = 0; h < height; h++)
{
// check each pixel for q number of ranges
for (int i = 0; i < q; i++)
{
if (image[w][h] <= rangesMax[i] && image[w][h] >= rangesMin[i])
{
image[w][h] = rangesMin[i];
}
}
}
}
return;
}
void pixelate(int image[][MAXHEIGHT], int width, int height, int n)
{
int updateW = 0;
int updateH = 0;
int nWidth = n;
int nHeight = n;
bool done = false;
while (!done)
{
int blockVal = 0; // will hold average value of block
for (int w = updateW; w < nWidth; w++)
{
for (int h = updateH; h < nHeight; h++)
{
blockVal += image[w][h];
}
}
blockVal /= (n*n);
blockVal = round(blockVal);
for (int w = updateW; w < nWidth; w++)
{
for (int h = updateH; h < nHeight; h++)
{
image[w][h] = blockVal;
}
}
if (updateW + n < 256 && updateH + n < 256)
{
updateH += n;
nHeight += n;
}
else if (updateW + n < 256 && updateH + n >= 256)
{
// reset horiz
updateH = 0;
nHeight = n;
updateW += n;
nWidth += n;
}
else if (updateW + n >= 256 && updateH + n < 256)
{
updateH += n;
nHeight += n;
}
else if (updateW + n + n >= 256 && updateH + n + n >= 256)
{
done = true;
}
}
return;
}
void edgeDet(int image[][MAXHEIGHT], int width, int height)
{
int ePixel; // holds the e pixel
int updWidth = 1;
int updHeight = 1;
int e, b, d, f, h; // vars for function
for (int w = 1; w < width - 2; w++) // exclude right edge
{
for (int col = 1; col < height - 2; col++)
{
e = image[w][col];
b = image[w][col - 1];
d = image[w - 1][col];
f = image[w + 1][col];
h = image[w][col + 1];
ePixel = 5 * e - (b + d + f + h); // function
if (ePixel > 255)
{
ePixel = 255;
}
else if (ePixel < 0)
{
ePixel = 0;
}
image[w][col] = ePixel;
}
}
}
void niceImage(int image[][MAXHEIGHT], int question, int width, int height)
{
if (question == 0)
{
int value, value2;
srand(time(0)); // random seed initialization
value = rand() % 100 + 1;
int task5Pix = 8;
pixelate(image, width, height, task5Pix);
value2 = rand() % 200 + 1;
highlight(image, width, height, value, value2);
int quantT5 = 16;
quantize(image, width, height, quantT5);
edgeDet(image, width, height);
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.