python 水下图像处理

2018-08-21 23:42:55 alvin93 阅读数 2104

2017-6 水下机器人视觉系统图像处理研究_仝灼银 
1.利用算法提高图像清晰度 
2.建立物理模型

(1)空域增强算法:直方图处理、对比度调整、图像分割——最热 
优化:部分统计加强、局部直方图调整、基于限制的混合对比度自适应直方图等

(2)频域增强算法:傅里叶变换、高斯滤波 
同态滤波、高斯滤波、高通滤波、选通滤波、小波变换—基于频域和时域,弥补傅里叶变换的不足,但有振铃现象。

(3)颜色恒常理论算法:白平衡理论 
(4)混合方法:前三种方法融合

自适应直方图均衡化—AHE,会出现过度增强噪点 
对比度限制的自适应直方图均衡化—CLAHE

清晰度评价方法 
均方误差—MSE 
峰值信噪比—PSNR

算法实现: 
图像从RGB空间经过算法处理分别变换到HSV和Lab颜色模型。再图像变换道HSV空间后,对V通道进行处理,再进行CLAHE算法处理,低照度部分将被增强,有效提升原图像的整体对比度。同时,采用加权方法对高频部分进行适当削弱,用来增强图像细节信息的对比度。在图像变换到Lab空间后,利用CLAHE算法对L通道进行处理,得到加强后的图片处理结果。

2019-08-03 20:04:39 yantuguiguziPGJ 阅读数 497

欢迎关注  公众号  土盐

 

知乎链接:

https://zhuanlan.zhihu.com/p/76472131

 

我要从背景中隔离一个物体(在我的例子中,金枪鱼)。问题是它们的颜色非常相似。

这是一个图像的例子:

对于隔离,我的意思是,创建一个countour或更改金枪鱼的颜色,或隔离我的对象的东西,因为我会根据形状进行对象检测。

有什么精心的设计,想法或技术可以应用处理于我的图像吗?

如果没有,我应该使用什么对象检测技术?

P.S:认为我不能使用背景减法,因为我的相机移动了一点..

此文献解释了水下图像的预处理 -

https://www.ensta-bretagne.fr/jaulin/paper_bazeille_CMM06.pdf

 

具体回答:

Background color similar to object color​answers.opencv.org图标

这种情况可以使用较小的预处理阈值和轮廓的亮度来解决。在这里,我想表明并非总是使用Hue色调。

这是模糊+均衡后的亮度及其直方图:

这是在选择金枪鱼的阈值和轮廓之后的最终结果

 

Background color similar to object color​

answers.opencv.org图标

这是代码。有一个半自动阈值,但我们也可以在直方图中选择适合的直方条来进行分割。使用滑块可得到处理效果。

这是代码。

#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;

int useEqualize = 0;
int th1, blursSize;
const std::string winName = "Tuna fish";
cv::Mat src, dst;
cv::Mat brightness;

void onTunaFishTrackbar(int, void*)
{
    cv::Mat hist, histImg, tmp;
    brightness.copyTo(tmp);

    if (blursSize >= 3)
    {
        blursSize += (1 - blursSize % 2);
        cv::GaussianBlur(tmp, tmp, cv::Size(blursSize, blursSize), 0);
    }
    if (useEqualize)
        cv::equalizeHist(tmp, tmp);

    cv::imshow("Brightness Preprocess", tmp);

    // threshold to select dark tuna
    cv::threshold(tmp, tmp, th1, 255, cv::THRESH_BINARY_INV);
    cv::imshow(winName, tmp);

    // find external contours ignores holes in the fish
    vector<vector<cv::Point> > contours;
    vector<cv::Vec4i> hierarchy;
    cv::findContours(tmp, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    // draw all contours and select the largest
    src.copyTo(dst);
    double maxDim = 0;
    int largest = -1;
    for (int i = 0; i < contours.size(); i++)
    {
        // draw all contours in red
        cv::drawContours(dst, contours, largest, cv::Scalar(0, 0, 255), 1);
        int dim = contours[i].size(); //area is more accurate but more expensive
        //double dim = contourArea(contours[i]);
        //double dim = cvRound(arcLength(contours[i], true));
        if (dim > maxDim)
        {
            maxDim = dim;
            largest = i;
        }
    }

    //The tuna as binary mask
    cv::Mat fishMask = cv::Mat::zeros(src.size(), CV_8UC1);
    //The tuna as contour
    vector<cv::Point> theFish;
    if (largest >= 0)
    {
        theFish = contours[largest];
        // draw selected contour in bold green
        cv::polylines(dst, theFish, true, cv::Scalar(0, 255, 0), 2);
        // draw the fish into its mask
        cv::drawContours(fishMask, contours, largest, 255, -1);
    }
    cv::imshow("Result Fish Mask", fishMask);
    cv::imshow("Result Contour", dst);
}

int main(int argc, char* argv[])
{
    src = cv::imread(argv[1]);
    if (src.empty())
    {
        cout << endl
            << "ERROR! Unable to read the image" << endl
            << "Press a key to terminate";
        cin.get();
        return 1;

    }

    imshow(winName, src);
    imshow("Src", src);

    cvtColor(src, dst, COLOR_BGR2HSV);
    vector<cv::Mat > hsv_planes;
    split(dst, hsv_planes);
    //hue = hsv_planes[0];
    //saturation = hsv_planes[1];
    brightness = hsv_planes[2];

    // default settings for params
    useEqualize = 1;
    blursSize = 21;
    th1 = 33.0 * 255 / 100; //tuna is dark than select dark zone below 33% of full range
    cv::createTrackbar("Equalize", winName, &useEqualize, 1, onTunaFishTrackbar, 0);
    cv::createTrackbar("Blur Sigma", winName, &blursSize, 100, onTunaFishTrackbar, 0);
    cv::createTrackbar("Threshold", winName, &th1, 255, onTunaFishTrackbar, 0);

    onTunaFishTrackbar(0, 0);

    cv::waitKey(0);
    return 0;
}

类似方案:

寻找复杂背景下物体的轮廓(OpenCV / C++ - Filling holes)

https://www.cnblogs.com/jsxyhelu/p/9758690.html

2019-05-19 21:53:58 qq_37487118 阅读数 1757

最近研究了dive+进行水下图像的增强效果,dive+是一款非常优秀的水下图像处理软件,试验发现dive+对某些强绿色水域的图片增强效果不好,例如下面的这幅图片(结果是我处理的)
QT写的测试Demo https://download.csdn.net/download/qq_37487118/11237929
在这里插入图片描述
用dive+处理颜色会偏黄,很可能dive+只考虑了水下图像中红色衰减比较厉害的情况,当然这符合大多数的情况,理论上也是正确的,但总有一些特殊的情况使得算法失效。
本次改进增加了水下图像增强算法的鲁棒性,使得本算法适用于绝大多数水下图像,贴一些最近水下图像的效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
效果貌似和dive+的效果差不多,如果加上去模糊(去雾之类的算法) 效果会更清晰,但这种算法并不能对所有图像都产生正向的效果,例如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
小丑鱼貌似就不太好看,不自然
去雾可能造成图像失真,饱和度过高,突出图像中的块效应,图像亮度降低
附上原图:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
图片可以去NASA、National Geography、Dive+ 去寻找

2018-11-25 14:48:46 qq_37487118 阅读数 3201

显然水下图像处理不能一概而论,对于不同水域的图像应该采取不同的方案进行处理,以前我所处理的水下图像大部分都是呈绿色,今天偶尔搜到了Dana Berman对水下图像的处理,个人认为他的水下图像处理效果一般,但提供的水下图像资源还是可以利用的,我对以前的水下图像处理过程增加了水域判断(简单的说就是看水呈蓝色还是绿色),然后进行了一些小改动,贴一下对蓝色的水下图像处理的主观效果图吧
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面的几张图片来自于Dive+,处理效果显然没有Dive+的溜
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另外附上一篇Ancuti 18年的水下图像处理文章,需要的大佬可以自己搜索下载
《Color Balance and Fusion for Underwater Image Enhancement》

2018-01-12 11:47:00 qq_21813987 阅读数 1395

如何使用python的numpy和python库中的PIL中的Image类进行图像的手绘处理

1. 手绘的情况要考虑原图的明暗程度以及光照的影响。

2. 图像的明暗程度的变化可以用grad u(i,j,k)梯度进行表示,直接调用numpy中的gradient(a)即可对ndarray数组进行梯度化

3.通过降维度函数convert('L'),将图像数组降为二维,进行灰度化

4.将光源效果,与深度depath对梯度的影响进行叠加

5.将处理后的数组通过Image.fromarray函数进行生成

im =np.array(Image.open('D:/dmeo.jpg').convert("L")).astype('float')

depath = 5 #对图像进行灰度降解的程度

grad = np.gradient(im) #计算图像对应的二维矩阵中的各个元素对应的梯度值,根据变化率来对各个像素点进行单位归一化

grad_x,grad_y = grad # x,y轴上面的梯度值,主要用来表示灰度的变化率

grad_x = grad_x*depath/100 #根据深度调整X,Y上的梯度值,进而影响灰度

grad_y = grad_y*depath/100

#求出立体坐标系下的梯度的模长

A = np.sqrt(grad_x**2+grad_y**2+1)#数学的模长计算公式

#进行单位化处理

uni_x = grad_x/A

uni_y = grad_y/A

uni_z = 1/A

#模拟光源对立体图像的影响

vec_el = np.pi/2.2

vec_ez = np.pi/4.

#下面分别是对X,Y,Z轴上面的影响

dx = np.cos(vec_el)*np.cos(vec_ez)

dy = np.cos(vec_el)*np.sin(vec_ez)

dz = np.sin(vec_el)

#将虚拟深度都灰度的影响以及光暗程度对灰度的影响叠加起来,并进行归一化

c = 255*(uni_x*dx+uni_y*dy+uni_z*dz)

#为了防止越界,进行区间裁剪

c = c.clip(0,255)

d = Image.fromarray(c.astype('uint8'))

d.save('D:/hello.png')


水下图像增强

阅读数 2517