# CS 585 HW1 Qitong Wang teammate name: Kaihong Wang, Yuankai He Date: Sep 11 2018

1.Problem discription:
I learned how to input an image into your code, process it, and output it.
The goal of this part of the assignment is to further familiarize you with programming with images.
My program took an image of my face as an input, manipulate it in three ways and then output the processed face:

(1) Create a grayscale image of your face by converting your color image using one of the conversions we discussed in class last week.
(2) Flip my face image horizontally and vertically.
(3) Come up with a third way of manipulating your face that produces an interesting output. I chose to show my negative cloor of my face picture.

The anticipated difficulty of solving these problem is that it is my first time to use OpenCV to deal with pictures directly, so I was a kind of unfamiliar with it and need some practices.

2. Method and Implementation:
(1)In the grayscale image work, I chose to calculate the mean RGB values of every pixels.
I used circulations to traversal every pixel of image which channels are 3 because colored map image's channels are 3.
The formula of each changed pixel is as fellows:
Pm = (R+G+B)/3
Then I used the Pm to replace the original pixels of images.
(2)In the image filpping work, I found a new Mat in order to store the filpped image of my face.
I used circulations to traversal every pixel of image which channels are 3 because colored map image's channels are 3.
When filpping horizontally, the horizontal pixeles of my original image are assigned to the new mat in the reverse order. (the orders of vertial pixels are unchangged)
When filpping vertically, the vertical pixeles of my original image are assigned to the new mat in the reverse order. (the orders of vertial pixels are unchangged)
(3)Speaking of my own idea, I tried to make a negative colored face image.
I used circulations to traversal every pixel of image which channels are 3 because colored map image's channels are 3.
So I chose to use the following formulas to get the new RGB values of pixels:
Rn = 255-R
Gn = 255-G
Bn = 255-B

3. Experiments:
In this experiment, I chose my formal picture of my face as original picture. In the main function of my project, I set up an switch sentence for choosing the ways of dealing with orignial pictures.
The switch directions are as fellows:
case 0: Getting the original face image.
case 1: Getting the grayscale of face image.
case 2: Getting the horizontal flipping of face image.
case 3: Getting the vertical flipping of face image.
case 4: Getting the negative colored picture of face image.
After showwing the changged picture, I used Imwrite function to store all the images.
The running time of the code is extremely short (less than one second for each change).

4. Result:
(1)the original image of my face:

(2)the grayscale image of my face comparing with the original face:

(3)the horizontal flipping image of my face comparing with the original image:

(By the way, you can diffientiate the changed images by looking the mole on my mouth and my hairstyle comparing with the original face image. Thank you! (: )
(4)the vertical flipping image of my face comparing with the original image:

(5)the negative colored image of my face comparing with original image:

5. Discussion:
It show that the results of the changed face images are quite sucessful and the project's efficiency is quite good.
I realized that there is many other kinds of changes of the images such as blurring, so in ther future, I could add blurring algorithms to deal with my face picture.

6. Conclusion:
In this experiment, I sucessfully finished the grayscale change, fliiping change and negative change of my face image. And the project could be better if I can add other change ways of my face image.

7.Credits and Bibliography:
(1) References:
[1]https://docs.opencv.org/3.0-beta/modules/imgcodecs/doc/reading_and_writing_images.html
[2]https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_core/py_basic_ops/py_basic_ops.html
(2) Team:
In this coding work, we all work independently.

Appendix:
A. Code:
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <string>

using namespace cv;
using namespace std;

String Path = "C:\\Users\\wqtwjt1996\\source\\repos\\Project1\\Project1\\";

int original()
{
Mat image;
image = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

int height = image.rows;
int width = image.cols;
int channels = image.channels();

for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
if (channels == 3)
{

image.at(x, y)[0] = image.at(x, y)[0];
image.at(x, y)[1] = image.at(x, y)[1];
image.at(x, y)[2] = image.at(x, y)[2];
}
}
}

namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image); // Show our image inside it.

waitKey(0); // Wait for a keystroke in the window
return 0;
}

int gray()
{
Mat image;
image = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

int height = image.rows;
int width = image.cols;
int channels = image.channels();

for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
if (channels == 3)
{
int m = 0;
for (int k = 0; k < 3; k++)
m += image.at(x, y)[k];
m = m / 3;

image.at(x, y)[0] = m;
image.at(x, y)[1] = m;
image.at(x, y)[2] = m;
}
}
}

namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image); // Show our image inside it.
imwrite(Path + "wqt_gray.bmp", image); // Store the changed images

waitKey(0); // Wait for a keystroke in the window
return 0;
}

int fh()
{
Mat image;
image = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

Mat image1;
image1 = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image1.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

int height = image.rows;
int width = image.cols;
int channels = image.channels();

for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
if (channels == 3)
{
image1.at(x, y)[0] = image.at(x, width - 1 - y)[0];
image1.at(x, y)[1] = image.at(x, width - 1 - y)[1];
image1.at(x, y)[2] = image.at(x, width - 1 - y)[2];
}
}
}

namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image1); // Show our image inside it.
imwrite("wqt_flip_horizontal.bmp", image1); // Store the changed images

waitKey(0); // Wait for a keystroke in the window
return 0;
}

int fv()
{
Mat image;
image = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

Mat image1;
image1 = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image1.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

int height = image.rows;
int width = image.cols;
int channels = image.channels();

for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
if (channels == 3)
{
image1.at(x, y)[0] = image.at(height - 1 - x, y)[0];
image1.at(x, y)[1] = image.at(height - 1 - x, y)[1];
image1.at(x, y)[2] = image.at(height - 1 - x, y)[2];
}
}
}

namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image1); // Show our image inside it.
imwrite("wqt_flip_vertical.bmp", image1); // Store the changed images

waitKey(0); // Wait for a keystroke in the window
return 0;
}

int own()
{
Mat image;
image = imread("wqt.jpg", IMREAD_UNCHANGED); // Read the file

if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return 0;
}

int height = image.rows;
int width = image.cols;
int channels = image.channels();

for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
if (channels == 3)
{
image.at(x, y)[0] = 255 - image.at(x, y)[0];
image.at(x, y)[1] = 255 - image.at(x, y)[1];
image.at(x, y)[2] = 255 - image.at(x, y)[2];
}
}
}

namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image); // Show our image inside it.
imwrite("wqt_negative.bmp", image); // Store the changed images

waitKey(0); // Wait for a keystroke in the window
return 0;
}

int main()
{
int a;
printf("Please select options:\n");
scanf("%d", &a);

switch (a)
{
case 0:original(); break;
case 1:gray(); break;
case 2:fh(); break;
case 3:fv(); break;
case 4:own(); break;
default:printf("input errors!\n"); break;
}
system("pause");
return 0;