Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
yoyoyo-yo committed Nov 21, 2019
1 parent 7f6323a commit b2213dc
Show file tree
Hide file tree
Showing 15 changed files with 761 additions and 54 deletions.
13 changes: 11 additions & 2 deletions Question_41_50/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ x = - sin(t) / cos(t) * y + r / cos(t)
## Q.47. モルフォロジー処理(膨張)
Morphology Dilate
*imori.jpg*を大津の二値化したものに、モルフォロジー処理による膨張を2回行え。
モルフォロジー処理とは二値化画像の白(255)マス部分を4近傍(上下左右1マス)に膨張、または1マスだけ収縮させる処理をいう。
Expand All @@ -198,10 +200,11 @@ x = - sin(t) / cos(t) * y + r / cos(t)
モルフォロジー処理の膨張(Dilation)アルゴリズムは、
注目画素I(x, y)=0で、I(x, y-1), I(x-1, y), I(x+1, y), I(x, y+1)のどれか一つが255なら、I(x, y) = 255 とする。
<img src='assets/morphology_erode.png' width=300>
つまり、上の処理を2回行えば2マス分膨張できることになる。
例えば、[[0,1,0], [1,0,1], [0,1,0]] のフィルタを掛けた和が255以上なら膨張である、と考える
モルフォロジー処理の実装は例えば、[[0,1,0], [1,0,1], [0,1,0]] のフィルタを掛けた和が255以上なら膨張である、と考えることもできる
|入力 (imori.jpg) |大津の二値化(answers_image/answer_4.jpg)|出力 (answers_image/answer_47.jpg)|
|:---:|:---:|:---:|
Expand All @@ -218,7 +221,9 @@ x = - sin(t) / cos(t) * y + r / cos(t)
モルフォロジー処理の収縮(Erosion)アルゴリズムは、
注目画素I(x, y)=255で、I(x, y-1), I(x-1, y), I(x+1, y), I(x, y+1)のどれか一つでも0なら、I(x, y) = 0 とする。
例えば、[[0,1,0], [1,0,1], [0,1,0]] のフィルタを掛けた和が255*4未満なら収縮である、と考える。
<img src='assets/morphology_dilate.png' width=300>
収縮処理は例えば、[[0,1,0], [1,0,1], [0,1,0]] のフィルタを掛けた和が255*4未満なら収縮である、と考えることもできる。
|入力 (imori.jpg) |大津の二値化(answers_image/answer_4.jpg)|出力 (answers_image/answer_48.jpg)|
|:---:|:---:|:---:|
Expand All @@ -234,6 +239,8 @@ x = - sin(t) / cos(t) * y + r / cos(t)
オープニング処理とは、モルフォロジー処理の収縮をN回行った後に膨張をN回行う処理である。
<img src='assets/morphology_opening.png' width=400>
オープニング処理により、一つだけ余分に存在する画素などを削除できる。
|入力 (imori.jpg) |大津の二値化(answers_image/answer_4.jpg)|出力 (answers_image/answer_49.jpg)|
Expand All @@ -248,6 +255,8 @@ x = - sin(t) / cos(t) * y + r / cos(t)
クロージング処理とは、モルフォロジー処理の膨張をN回行った後に収縮をN回行う処理である。
<img src='assets/morphology_closing.png' width=400>
クロージング処理により、途中で途切れた画素を結合することができる。
|入力 (imori.jpg) |Canny(answers_image/answer_43.jpg)|出力 (answers_image/answer_50.jpg)|
Expand Down
2 changes: 1 addition & 1 deletion Question_41_50/answers_cpp/answer_43.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ int main(int argc, const char* argv[]){
// read image
cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);

// Canny step 2
// Canny
cv::Mat edge = Canny(img);

//cv::imwrite("out.jpg", out);
Expand Down
217 changes: 217 additions & 0 deletions Question_41_50/answers_cpp/answer_49.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>

// BGR -> Gray
cv::Mat BGR2GRAY(cv::Mat img){
// get height and width
int width = img.cols;
int height = img.rows;

// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC1);

// each y, x
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
// BGR -> Gray
out.at<uchar>(y, x) = 0.2126 * (float)img.at<cv::Vec3b>(y, x)[2] \
+ 0.7152 * (float)img.at<cv::Vec3b>(y, x)[1] \
+ 0.0722 * (float)img.at<cv::Vec3b>(y, x)[0];
}
}

return out;
}

// Gray -> Binary
cv::Mat Binarize_Otsu(cv::Mat gray){
int width = gray.cols;
int height = gray.rows;

// determine threshold
double w0 = 0, w1 = 0;
double m0 = 0, m1 = 0;
double max_sb = 0, sb = 0;
int th = 0;
int val;

// Get threshold
for (int t = 0; t < 255; t++){
w0 = 0;
w1 = 0;
m0 = 0;
m1 = 0;
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
val = (int)(gray.at<uchar>(y, x));

if (val < t){
w0++;
m0 += val;
} else {
w1++;
m1 += val;
}
}
}

m0 /= w0;
m1 /= w1;
w0 /= (height * width);
w1 /= (height * width);
sb = w0 * w1 * pow((m0 - m1), 2);

if(sb > max_sb){
max_sb = sb;
th = t;
}
}

std::cout << "threshold:" << th << std::endl;

// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC1);

// each y, x
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
// Binarize
if (gray.at<uchar>(y, x) > th){
out.at<uchar>(y, x) = 255;
} else {
out.at<uchar>(y, x) = 0;
}

}
}

return out;
}

// Morphology Erode
cv::Mat Morphology_Erode(cv::Mat img, int Erode_time){
int height = img.cols;
int width = img.rows;

// output image
cv::Mat tmp_img;
cv::Mat out = img.clone();

// for erode time
for (int i = 0; i < Erode_time; i++){
tmp_img = out.clone();

// each pixel
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
// check left pixel
if ((x > 0) && (tmp_img.at<uchar>(y, x - 1) == 255)){
out.at<uchar>(y, x) = 255;
continue;
}

// check up pixel
if ((y > 0) && (tmp_img.at<uchar>(y - 1, x) == 255)){
out.at<uchar>(y, x) = 255;
continue;
}

// check right pixel
if ((x < width - 1) && (tmp_img.at<uchar>(y, x + 1) == 255)){
out.at<uchar>(y, x) = 255;
continue;
}

// check left pixel
if ((y < height - 1) && (tmp_img.at<uchar>(y + 1, x) == 255)){
out.at<uchar>(y, x) = 255;
continue;
}
}
}
}

return out;
}

// Morphology Dilate
cv::Mat Morphology_Dilate(cv::Mat img, int Dilate_time){
int height = img.cols;
int width = img.rows;

// output image
cv::Mat tmp_img;
cv::Mat out = img.clone();

// for erode time
for (int i = 0; i < Dilate_time; i++){
tmp_img = out.clone();

// each pixel
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
// check left pixel
if ((x > 0) && (tmp_img.at<uchar>(y, x - 1) == 0)){
out.at<uchar>(y, x) = 0;
continue;
}

// check up pixel
if ((y > 0) && (tmp_img.at<uchar>(y - 1, x) == 0)){
out.at<uchar>(y, x) = 0;
continue;
}

// check right pixel
if ((x < width - 1) && (tmp_img.at<uchar>(y, x + 1) == 0)){
out.at<uchar>(y, x) = 0;
continue;
}

// check left pixel
if ((y < height - 1) && (tmp_img.at<uchar>(y + 1, x) == 0)){
out.at<uchar>(y, x) = 0;
continue;
}
}
}
}

return out;
}

// Morphology opening
cv::Mat Morphology_Opening(cv::Mat img, int open_time){

// Morphology dilate
img = Morphology_Dilate(img, open_time);

// Morphology erode
img = Morphology_Erode(img, open_time);

return img;
}


int main(int argc, const char* argv[]){
// read image
cv::Mat img = cv::imread("imori.jpg", cv::IMREAD_COLOR);

// BGR -> Gray
cv::Mat gray = BGR2GRAY(img);

// Gray -> Binary
cv::Mat bin = Binarize_Otsu(gray);

// Morphology Opening
cv::Mat out = Morphology_Opening(bin, 1);

//cv::imwrite("out.jpg", out);
cv::imshow("sample", out);
cv::waitKey(0);
cv::destroyAllWindows();

return 0;
}
Loading

0 comments on commit b2213dc

Please sign in to comment.