图像处理编程中的mask_Opencv从图像中去除眩光

本文探讨了如何使用OpenCV在图像处理中去除眩光,同时尽量保持图像的细节,如网格信息。作者尝试了不同的方法,最终采用C++算法,通过HSV通道分离、阈值分割和颜色填充实现。在Python环境下也有实现方式。
摘要由CSDN通过智能技术生成

333ca0127bea376baee8a934ca7cacef.png

眩光治疗法师登场。

待处理眩光图

grids.png

900b55e09828ffc50f9b06c2f3383d93.png

一个Matlab代码提示

How to remove the glare and brightness in an image (Image preprocessing)?

m_img = cv2.medianBlur(img,5)

ret,th1 = cv2.threshold(m_img,180,255,cv2.THRESH_BINARY)

timg = cv2.inpaint(cimg,th1,9,cv2.INPAINT_NS)

结果不美好,错误示范

f1c719946776a56a855503afddb3f263.png

这个改进失去了我想要的网格信息

这里有个提示

How to remove glare from image

但我在图像处理中找不到任何偏振滤镜实现。

任何人都可以建议任何改进,这样我可以在不丢失网格的情况下失去眩光吗?

解决方案:

C++算法大致步骤:HSV通道分离,阈值分割,再填充颜色。255判断那里是对分割后的二值图进行操作。

#include <iostream>

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

int main(int argc, char** argv)

{

	// Load main image
	Mat bgr_frame = imread("grids.png");

	if (bgr_frame.empty())
	{
		cout << "Error loading image file" << endl;
		return -1;
	}

	// Convert from BGR to HSV
	Mat hsv_frame;
	//cvtColor(bgr_frame, hsv_frame, CV_BGR2HSV);
	cvtColor(bgr_frame, hsv_frame, COLOR_BGR2HSV);
	// Split HSV into H, S, V channels
	Mat channels[3];
	split(hsv_frame, channels);

	// Get mask
	//threshold(channels[0], channels[0], 63, 255, CV_THRESH_BINARY);
	threshold(channels[0], channels[0], 63, 255, THRESH_BINARY);
	// Use mask to generate a BGR image
	Mat output(channels[0].rows, channels[0].cols, CV_8UC3);

	for (int j = 0; j < channels[0].rows; j++)
	{
		for (int i = 0; i < channels[0].cols; i++)
		{
			unsigned char val = channels[0].at<unsigned char>(j, i);

			if (255 == val)
			{
				output.at<Vec3b>(j, i)[0] = 189;
				output.at<Vec3b>(j, i)[1] = 108;
				output.at<Vec3b>(j, i)[2] = 47;
			}
			else
			{
				output.at<Vec3b>(j, i)[0] = 94;
				output.at<Vec3b>(j, i)[1] = 206;
				output.at<Vec3b>(j, i)[2] = 236;
			}
		}
	}

	imshow("hue", channels[0]);
	imshow("output", output);
	waitKey();


	destroyAllWindows();

	return 0;

}

自己动手实现的结果

配置环境:opencv4.0,VS2017

特别注意:

cvtColor(bgr_frame, hsv_frame, COLOR_BGR2HSV);
threshold(channels[0], channels[0], 63, 255, THRESH_BINARY);

5f55b92a9560c37c69073339e9bfe690.png

从这个图的效果看,是对原图二值化后,填充颜色与原图近似的效果。

How to remove these small glare from the image?​answers.opencv.org

python实现

import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import k_means
​
​
img = cv2.imread("./grids.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = ((img_hsv > np.array([0, 0, 230])).astype(np.float32) + (img_hsv > np.array([0, 0, 230])).astype(np.float32) * (-0.5) + 0.5)
img_partly_darken = cv2.cvtColor(mask * img_hsv, cv2.COLOR_HSV2BGR)
plt.imshow(cv2.cvtColor(img_partly_darken, cv2.COLOR_BGR2RGB))
plt.show()
​
cv2.imwrite("t.png", img_partly_darken)# Save the img now, and ... Surprise! You can feel the mystery:
plt.imshow(cv2.cvtColor(cv2.imread("t.png"), cv2.COLOR_BGR2RGB))
plt.show()
​
# Then, you can just pick out the green ones:
green_mask = img[:, :, 1] > img[:, :, 2] # value of green channel > that of red channel# Here is a trick, I use color space convertion to boardcast one channel to three channels
green_mask = (green_mask.astype(np.uint8)) * 255
green_mask = cv2.cvtColor(green_mask, cv2.COLOR_GRAY2BGR)
green3_mask = (green_mask > 0).astype(np.uint8) * 255
img_green = cv2.bitwise_and(green3_mask, img)
plt.imshow(cv2.cvtColor(img_green, cv2.COLOR_BGR2RGB))
plt.show()
​
# Back to the original img's colors:
ret, thr = cv2.threshold(cv2.cvtColor(img_green, cv2.COLOR_BGR2GRAY), 10, 255, cv2.THRESH_BINARY)
blue_mask = (cv2.cvtColor(thr, cv2.COLOR_GRAY2BGR) > 0).astype(np.uint8) * 255
kernel_open =cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
blue_mask = cv2.morphologyEx(blue_mask, cv2.MORPH_OPEN, kernel_open)
yellow_mask = 255 - blue_mask
​
# use k-means to get the two main colors -- blue and yellow
pixels = img
pixels = pixels.reshape(pixels.shape[0] * pixels.shape[1], 3)[centroids, labels, inertia] = k_means(pixels, 2)
centroids = np.array(sorted(centroids.astype(np.uint8).tolist(), key=lambda x: x[0])) # B channel
blue_centroid = centroids[1]
yellow_centroid = centroids[0]
blue_ones = cv2.bitwise_and(blue_mask, centroids[1])
yellow_ones = cv2.bitwise_and(yellow_mask, centroids[0])
plt.imshow(cv2.cvtColor(cv2.add(blue_ones, yellow_ones), cv2.COLOR_BGR2RGB))
plt.show()
https://answers.opencv.org/question/179998/how-to-remove-these-small-glare-from-the-image/​answers.opencv.org

c6add6b642ed65061901b24046fcbd55.png

598747fa7af3f7ea70ed141b9d74e901.png

fe261871294acbf3232d3c50b47abf76.png

12449b8b6cce904a277f933cc78a2ff9.png

db8d60cf9f022c45390095205936aea6.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值