using OpenCvSharp;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
Mat im = Cv2.ImRead("../../../images/YZeOg.jpg");
// 原图有点大。。。
Cv2.Resize(im, im, new Size(im.Cols * 0.5, im.Rows * 0.5));
Cv2.ImShow("im", im);
Mat gr = new Mat();
Mat bg = new Mat();
Mat bw = new Mat();
Mat dark = new Mat();
Cv2.CvtColor(im, gr, ColorConversionCodes.BGR2GRAY);
// approximate the background
gr.CopyTo(bg);
for (int r = 1; r < 5; r++)
{
Mat kernel2 = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(2 * r + 1, 2 * r + 1));
Cv2.MorphologyEx(bg, bg, MorphTypes.Close, kernel2);
Cv2.MorphologyEx(bg, bg, MorphTypes.Open, kernel2);
}
// difference = background - initial
Mat dif = bg - gr;
// threshold the difference image so we get dark letters
Cv2.Threshold(dif, bw, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
// threshold the background image so we get dark region
Cv2.Threshold(bg, dark, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
// extract pixels in the dark region
byte[] darkpix = new byte[Cv2.CountNonZero(dark)];
int index = 0;
for (int r = 0; r < dark.Rows; r++)
{
for (int c = 0; c < dark.Cols; c++)
{
if (dark.At<byte>(r, c) > 0)
{
darkpix[index++] = gr.At<byte>(r, c);
}
}
}
Mat mat = Mat.FromArray(darkpix);
// threshold the dark region so we get the darker pixels inside it
Cv2.Threshold(mat, mat, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
mat.GetArray(out darkpix);
// paste the extracted darker pixels
index = 0;
for (int r = 0; r < dark.Rows; r++)
{
for (int c = 0; c < dark.Cols; c++)
{
if (dark.At<byte>(r, c) > 0)
{
bw.At<byte>(r, c) = darkpix[index++];
}
}
}
Cv2.ImShow("BW", bw);
Cv2.WaitKey(0);
}
}
}
C++版本代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat im = imread("../images/YZeOg.jpg");
// 原图有点大。。。
//resize(im, im, Size(im.cols * 0.5, im.rows * 0.5), (0, 0), (0, 0), 3);
imshow("im", im);
Mat gr, bg, bw, dark;
cvtColor(im, gr, COLOR_BGR2GRAY);
// approximate the background
bg = gr.clone();
for (int r = 1; r < 5; r++)
{
Mat kernel2 = getStructuringElement(MORPH_ELLIPSE, Size(2 * r + 1, 2 * r + 1));
morphologyEx(bg, bg, MORPH_CLOSE, kernel2);
morphologyEx(bg, bg, MORPH_OPEN, kernel2);
}
// difference = background - initial
Mat dif = bg - gr;
// threshold the difference image so we get dark letters
threshold(dif, bw, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
// threshold the background image so we get dark region
threshold(bg, dark, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
// extract pixels in the dark region
vector<unsigned char> darkpix(countNonZero(dark));
int index = 0;
for (int r = 0; r < dark.rows; r++)
{
for (int c = 0; c < dark.cols; c++)
{
if (dark.at<unsigned char>(r, c))
{
darkpix[index++] = gr.at<unsigned char>(r, c);
}
}
}
// threshold the dark region so we get the darker pixels inside it
threshold(darkpix, darkpix, 0, 255, THRESH_BINARY | THRESH_OTSU);
// paste the extracted darker pixels
index = 0;
for (int r = 0; r < dark.rows; r++)
{
for (int c = 0; c < dark.cols; c++)
{
if (dark.at<unsigned char>(r, c))
{
bw.at<unsigned char>(r, c) = darkpix[index++];
}
}
}
imshow("BW", bw);
waitKey(0);
}
Python版本代码如下
Python的效果貌似没C++和C#的效果好~~
# Import the necessary packages
import cv2
import numpy as np
def back_rm(filename):
# Load the image
img = cv2.imread(filename)
# Convert the image to grayscale
gr = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Make a copy of the grayscale image
bg = gr.copy()
# Apply morphological transformations
for i in range(5):
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,
(2 * i + 1, 2 * i + 1))
bg = cv2.morphologyEx(bg, cv2.MORPH_CLOSE, kernel2)
bg = cv2.morphologyEx(bg, cv2.MORPH_OPEN, kernel2)
# Subtract the grayscale image from its processed copy
dif = cv2.subtract(bg, gr)
# Apply thresholding
bw = cv2.threshold(dif, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
dark = cv2.threshold(bg, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
# Extract pixels in the dark region
darkpix = gr[np.where(dark > 0)]
# Threshold the dark region to get the darker pixels inside it
darkpix = cv2.threshold(darkpix, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# Paste the extracted darker pixels in the watermark region
bw[np.where(dark > 0)] = darkpix.T
bw = cv2.resize(bw, (int(bw.shape[1] * 0.5), int(bw.shape[0] * 0.5)), interpolation=cv2.INTER_NEAREST)
cv2.imshow('final.jpg', bw)
cv2.waitKey(0)
back_rm('../images/YZeOg.jpg')
using OpenCvSharp;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
Mat im = Cv2.ImRead("../../../images/YZeOg.jpg");
// 原图有点大。。。
Cv2.Resize(im, im, new Size(im.Cols * 0.5, im.Rows * 0.5));
Cv2.ImShow("im", im);
Mat gr = new Mat();
Mat bg = new Mat();
Mat bw = new Mat();
Mat dark = new Mat();
Cv2.CvtColor(im, gr, ColorConversionCodes.BGR2GRAY);
// approximate the background
gr.CopyTo(bg);
for (int r = 1; r < 5; r++)
{
Mat kernel2 = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(2 * r + 1, 2 * r + 1));
Cv2.MorphologyEx(bg, bg, MorphTypes.Close, kernel2);
Cv2.MorphologyEx(bg, bg, MorphTypes.Open, kernel2);
}
// difference = background - initial
Mat dif = bg - gr;
// threshold the difference image so we get dark letters
Cv2.Threshold(dif, bw, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
// threshold the background image so we get dark region
Cv2.Threshold(bg, dark, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
// extract pixels in the dark region
byte[] darkpix = new byte[Cv2.CountNonZero(dark)];
int index = 0;
for (int r = 0; r < dark.Rows; r++)
{
for (int c = 0; c < dark.Cols; c++)
{
if (dark.At<byte>(r, c) > 0)
{
darkpix[index++] = gr.At<byte>(r, c);
}
}
}
Mat mat = Mat.FromArray(darkpix);
// threshold the dark region so we get the darker pixels inside it
Cv2.Threshold(mat, mat, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
mat.GetArray(out darkpix);
// paste the extracted darker pixels
index = 0;
for (int r = 0; r < dark.Rows; r++)
{
for (int c = 0; c < dark.Cols; c++)
{
if (dark.At<byte>(r, c) > 0)
{
bw.At<byte>(r, c) = darkpix[index++];
}
}
}
Cv2.ImShow("BW", bw);
Cv2.WaitKey(0);
}
}
}
C++版本代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat im = imread("../images/YZeOg.jpg");
// 原图有点大。。。
//resize(im, im, Size(im.cols * 0.5, im.rows * 0.5), (0, 0), (0, 0), 3);
imshow("im", im);
Mat gr, bg, bw, dark;
cvtColor(im, gr, COLOR_BGR2GRAY);
// approximate the background
bg = gr.clone();
for (int r = 1; r < 5; r++)
{
Mat kernel2 = getStructuringElement(MORPH_ELLIPSE, Size(2 * r + 1, 2 * r + 1));
morphologyEx(bg, bg, MORPH_CLOSE, kernel2);
morphologyEx(bg, bg, MORPH_OPEN, kernel2);
}
// difference = background - initial
Mat dif = bg - gr;
// threshold the difference image so we get dark letters
threshold(dif, bw, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
// threshold the background image so we get dark region
threshold(bg, dark, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
// extract pixels in the dark region
vector<unsigned char> darkpix(countNonZero(dark));
int index = 0;
for (int r = 0; r < dark.rows; r++)
{
for (int c = 0; c < dark.cols; c++)
{
if (dark.at<unsigned char>(r, c))
{
darkpix[index++] = gr.at<unsigned char>(r, c);
}
}
}
// threshold the dark region so we get the darker pixels inside it
threshold(darkpix, darkpix, 0, 255, THRESH_BINARY | THRESH_OTSU);
// paste the extracted darker pixels
index = 0;
for (int r = 0; r < dark.rows; r++)
{
for (int c = 0; c < dark.cols; c++)
{
if (dark.at<unsigned char>(r, c))
{
bw.at<unsigned char>(r, c) = darkpix[index++];
}
}
}
imshow("BW", bw);
waitKey(0);
}
Python版本代码如下
Python的效果貌似没C++和C#的效果好~~
# Import the necessary packages
import cv2
import numpy as np
def back_rm(filename):
# Load the image
img = cv2.imread(filename)
# Convert the image to grayscale
gr = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Make a copy of the grayscale image
bg = gr.copy()
# Apply morphological transformations
for i in range(5):
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,
(2 * i + 1, 2 * i + 1))
bg = cv2.morphologyEx(bg, cv2.MORPH_CLOSE, kernel2)
bg = cv2.morphologyEx(bg, cv2.MORPH_OPEN, kernel2)
# Subtract the grayscale image from its processed copy
dif = cv2.subtract(bg, gr)
# Apply thresholding
bw = cv2.threshold(dif, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
dark = cv2.threshold(bg, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
# Extract pixels in the dark region
darkpix = gr[np.where(dark > 0)]
# Threshold the dark region to get the darker pixels inside it
darkpix = cv2.threshold(darkpix, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# Paste the extracted darker pixels in the watermark region
bw[np.where(dark > 0)] = darkpix.T
bw = cv2.resize(bw, (int(bw.shape[1] * 0.5), int(bw.shape[0] * 0.5)), interpolation=cv2.INTER_NEAREST)
cv2.imshow('final.jpg', bw)
cv2.waitKey(0)
back_rm('../images/YZeOg.jpg')