• clc;clear all; N=imread('图片1.png'); r1=0; r2=75; s1=0; s2=255; k=(s2-s1)/(r2-r1); b=s1-k*r1; [r,c]=size(N); N1=im2double(N); for x=1:r for y=1:c tmp=N1(x,y);...title('对比度拉伸图像');
clc;clear all;
N=imread('图片1.png'); r1=0; r2=75; s1=0; s2=255; k=(s2-s1)/(r2-r1); b=s1-k*r1;
[r,c]=size(N); N1=im2double(N);
for x=1:r for y=1:c tmp=N1(x,y); if tmp>=r1 && tmp<=r2 N1(x,y)=k*tmp+b; end end end subplot(1,2,1);imshow(N);title('原图像'); subplot(1,2,2);imshow(N1);title('对比度拉伸后图像');

展开全文
• 图像灰度拉神，主要是将图像的灰度拉伸至全灰度区间，计算公式如下： xaml代码 <Window x:Class="ImageProcess_GrayStretch.MainWindow" xmlns=...
图像灰度拉神，主要是将图像的灰度拉伸至全灰度区间，计算公式如下：

xaml代码
<Window x:Class="ImageProcess_GrayStretch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ImageProcess_GrayStretch"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Name="img" Stretch="Uniform"/>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Content="Gray Stretch" Margin="5" Click="GrayStretch_Click"/>
</StackPanel>
</Grid>
</Window>

后台代码
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace ImageProcess_GrayStretch
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private byte GetMaxValue(byte[] rgbValues)
{
byte maxi = rgbValues[0];
for (int i = 0; i < rgbValues.Length; i++)
{
if (maxi < rgbValues[i])
{
maxi = rgbValues[i];
}
}
return maxi;
}

private byte GetMinValue(byte[] rgbValues)
{
byte mini = rgbValues[0];
for (int i = 0; i < rgbValues.Length; i++)
{
if (mini > rgbValues[i])
{
mini = rgbValues[i];
}
}
return mini;
}

private void BitmapGrayStretch(Bitmap curBitmap, int width, int height)
{
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, width, height);
BitmapData bmpData = curBitmap.LockBits(rect, ImageLockMode.ReadWrite, curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = width * height * 4;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
byte[] matGray = new byte[width * height];
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
byte alpha = rgbValues[i + 3];
byte red = rgbValues[i + 2];
byte green = rgbValues[i + 1];
byte blue = rgbValues[i];
byte gray = (byte)(red * 0.299 + green * 0.587 + blue * 0.114);
matGray[i / 4] = gray;
}
byte maxGray = GetMaxValue(matGray);
byte minGray = GetMinValue(matGray);
double f = 0;
if (maxGray != minGray)
{
f = 255.0 / (maxGray - minGray);
}
for (int i = 0; i < rgbValues.Length; i = i + 4)
{
rgbValues[i] = (byte)(f * (matGray[i / 4] - minGray));
rgbValues[i + 1] = (byte)(f * (matGray[i / 4] - minGray));
rgbValues[i + 2] = (byte)(f * (matGray[i / 4] - minGray));
}
Marshal.Copy(rgbValues, 0, ptr, bytes);
curBitmap.UnlockBits(bmpData);
}

private Bitmap ImageSourceToBitmap(ImageSource imageSource)
{
BitmapSource bitmapSource = (BitmapSource)imageSource;
Bitmap bmp = new Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
BitmapData data = bmp.LockBits(
new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
bitmapSource.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);
return bmp;
}

private BitmapImage BitmapToBitmapImage(Bitmap bitmap)
{
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);
stream.Position = 0;
BitmapImage result = new BitmapImage();
result.BeginInit();
result.StreamSource = stream;
result.EndInit();
result.Freeze();
return result;
}
}

private void Load_Click(object sender, RoutedEventArgs e)
{
img.Source = new BitmapImage(new Uri(@"D:\程序项目目录\ImgList\World.jpg", UriKind.RelativeOrAbsolute));
}

private void GrayStretch_Click(object sender, RoutedEventArgs e)
{
Bitmap bitmap = ImageSourceToBitmap(img.Source);
BitmapGrayStretch(bitmap, bitmap.Width, bitmap.Height);
img.Source = BitmapToBitmapImage(bitmap);
}
}
}

技术要领： 采用内存方式一次性加载整个图片，效率高，如果用循环的方式，采用GetPixel方式来获取像素RGB值，效率极低，这幅图片的size为2048*1025，循环方式特别慢。
展开全文
• 图像灰度拉伸 文章目录1 原理2 Matlab实现3 OpenCV实现4 效果 1 原理   图像灰度拉伸是改变图像对比度的一种方法，通过灰度映射，将原图中某一区段中的灰度值映射到另一灰度值，从而拉伸或压缩整个图像的灰度...
图像灰度拉伸

文章目录
1 原理2 Matlab实现3 OpenCV实现4 效果

1 原理
图像灰度拉伸是改变图像对比度的一种方法，通过灰度映射，将原图中某一区段中的灰度值映射到另一灰度值，从而拉伸或压缩整个图像的灰度分布范围。
2 Matlab实现
clc;
clear;
close all;

% 对灰度图进行灰度线性变换
ori_img1 = rgb2gray(ori_img);
[oriHist,oriX] = imhist(ori_img1);

pt0 = [0,0];
pt1 = [100,50];
pt2 = [150,160];
pt3 = [255,200];

[width,height] = size( ori_img1);
gray1 = ori_img1;
for i=1:1:width
for j = 1:1:height
if (gray1(i,j)<pt1(1))
gray1(i,j) = pt0(2) + (gray1(i,j)-pt0(1)) * ((pt1(2)-pt0(2))/(pt1(1)-pt0(1)));
else if(gray1(i,j)>=pt1(1)&&gray1(i,j)<pt2(1))
gray1(i,j) = pt1(2) + (gray1(i,j)-pt1(1)) * ((pt2(2)-pt1(2))/(pt2(1)-pt1(1)));
else
gray1(i,j) = pt2(2) + (gray1(i,j)-pt2(1)) * ((pt3(2)-pt2(2))/(pt3(1)-pt2(1)));
end
end
end
end
[g1Hist,g1X] = imhist(gray1);
figure(1),subplot(1,2,1),imshow(ori_img1),title('原图');subplot(1,2,2),imshow(gray1),title('灰度线性拉伸');
figure(2),subplot(1,2,1),stem(oriX,oriHist),title('原图直方图');subplot(1,2,2),stem(g1X,g1Hist),title('灰度线性拉伸直方图');


3 OpenCV实现
//
int cvPointCmp(cv::Point& a, cv::Point& b)
{
return a.x < b.x;
}

//根据控制点，生成灰度拉伸所使用的查找表
void CreateLSLUT(std::vector<cv::Point>& pts, cv::Mat& lut)
{
if (pts.size() == 0)
return;
//在控制点前增加(0,0)点，末尾增加(255,255)点
std::vector<cv::Point> npts(1, cv::Point(0, 0));
npts.insert(npts.end(), pts.begin(), pts.end());
npts.push_back(cv::Point(255, 255));
//根据点的X坐标排序
std::sort(npts.begin(), npts.end(), cvPointCmp);

lut = cv::Mat(1, 256, CV_8UC1);
int nLoc = 0;
for (int i = 0; i < 256; i++)
{
for (int j = nLoc; j < npts.size()-1; j++)
{
//找出i所对应的区间的端点，左闭右开区间
if (npts[j].x <= i && npts[j+1].x > i)
{
nLoc = j;
float y = npts[j].y + 1.0*(npts[j + 1].y - npts[j].y) / (npts[j + 1].x - npts[j].x)*(i - npts[j].x);
if (y < 0)
y = 0;
if (y > 255)
y = 255;
lut.at<uchar>(i) = (uchar)y;
break;
}
}
}
}

#include "../include/baseOps.h"
#include <iostream>
#include <string>
#include "../include/opencv400/opencv2/opencv.hpp"
#include "windows.h"

int main()
{
SetCurrentDirectoryToExePath();

cv::Mat ori_img = cv::imread("../images/6.jpg");
cv::Mat gray_img;
cv::cvtColor(ori_img, gray_img, cv::COLOR_BGR2GRAY);
cv::namedWindow("灰度图");
cv::imshow("灰度图", gray_img);

cv::Mat grayHist;
calcHist1D(gray_img, grayHist);
cv::imshow("hist", grayHist);

//确定控制点
std::vector<cv::Point> pts;
pts.push_back(cv::Point(50, 100));
pts.push_back(cv::Point(100, 80));
pts.push_back(cv::Point(80, 120));
pts.push_back(cv::Point(250, 80));

//生成灰度映射表
cv::Mat lut;
CreateLSLUT(pts, lut);

//查表操作
cv::Mat res;
cv::LUT(gray_img, lut, res);

cv::Mat g1Hist;
calcHist1D(res, g1Hist);
cv::imshow("g1", res);
cv::imshow("g1Hist", g1Hist);

cv::waitKey();
return 0;
}

4 效果

展开全文
• 通过灰度拉伸可加大图像的对比度，使图像变得更加清晰。 灰度拉伸分为线性拉伸和非线性拉伸两种方法。 1、线性拉伸对像素值进行线性比例变化，主要有以下几种方法： 全域线性拉伸 2%线性拉伸 分段线性拉伸 ...
成像系统只能获取一定亮度范围内的值。由于成像系统的量化级数有限，常出现对比度不足的弊病，图像看起来比较模糊、暗淡。通过灰度拉伸可加大图像的对比度，使图像变得更加清晰。
灰度拉伸分为线性拉伸和非线性拉伸两种方法。
1、线性拉伸对像素值进行线性比例变化，主要有以下几种方法：
全域线性拉伸2%线性拉伸分段线性拉伸灰度窗口切片（可将某一区间内的灰度级和其他部分分开）
2、非线性拉伸使用非线性函数对图像进行拉伸变化，常用的非线性函数有指数函数、对数函数、平方根、高斯函数等。其中，指数变换对于图像中亮的部分，它扩大了灰度间隔，突出了细节；对于暗的部分，它缩小了灰度间隔，弱化了细节。与指数变换相反，对数变换主要用于拉伸图像中暗的部分，而压缩亮的部分。
展开全文
• 该算法主要是在图像处理过程中对图像灰度进行拉伸处理。
• 图像灰度级放缩至我们指定的预期期间，即用【处理后的灰度级最小值】加上“ 【步骤3中归一化处理后的结果】乘以【处理后的灰度级最大值-处理后的灰度级最小值】 ”； 将处理后的图像转为uint8类型以便于正确显示。...
• 定义：灰度拉伸，也称对比度拉伸，是一种简单的线性点运算。作用：扩展图像的 直方图，使其充满整个灰度等级范围内 公式： g(x,y) = 255 / (B - A) * [f(x,y) - A], 其中，A = min[f(x,y)],最小灰度级；B = max[f(x...
• ## 灰度图像拉伸方法

千次阅读 2016-08-11 19:22:04
1.找到该灰度图像灰度值的最大值(max_value)和最小值(min_value) 2.确定拉伸后的灰度范围HistogramStrench_min~HistogramStrench_max 3.遍历灰度图像(image)得到拉伸后的灰度图像 公式如下: image[i] = ...
• 灰度拉伸可以更加灵活的控制输出灰度直方图的分布，它可以有选择的拉伸某段灰度区间以改善输出图像。 如上图，所示的变换函数的运算结果是将原图在A.x对应灰度转换成A.y对应灰度. 同理B也是. 上图X, Y...
• 灰度拉伸图像增强的一种，它是把分离的灰度转换到比较集中的程度，这时就更利于分析。  代码如下： [cpp] view plaincopyprint? /*************************************************************...
• 实验内容及实验原理：1、灰度的线性变换灰度的线性变换就是将图像中所有的点的灰度按照线性灰度变换函数进行变换。该线性灰度变换函数是一个...2、灰度拉伸灰度拉伸和灰度线性变换相似。不同之处在于它是分段线性变...
• 这样增加了灰度值的动态范围，从而达到增强图像整体对比度的效果。算法步骤：1）计算图像f(x,y)的各灰度级中像素出现的概率p(i)。 p(i)=nin,i=0,1,...,L−1(L：灰度级个数)p(i)=\frac{n_i}{n},i=0,1,...,L-1 (L：...
• 书中所有的实验与数学式都采用了8-bit 图像灰度范围，也就是0到255这样一个范围，这是本书不合理的一个地方。首先，这样做并不泛用，图片不一定是8-bit的。其次，在做某些变换的时候，可能会导致溢出。比如，伽马....
• 一、基本知识 图像对比度是指：一副图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量，差异范围越大代表对比度越大；一般来说图像对比度越大，图像越清晰醒目，色彩也越鲜明...直方图均衡化以及灰度拉伸都...
• 题目：定义一个图像的对比度拉伸函数，函数名为myGrayScaleTransform，将输入图像的对比度线性平滑地拉伸到指定的灰度级区间，要求该函数的输入参数包括处理前的灰度图像img1 (如EXP1A.tif)、期望灰度级的参数区间...
• 灰度变换是图像增强的一种重要手段，用于改善图像显示效果，属于空间域处理方法，它可以使图像动态范围加大，使图像对比度扩展，图像更加清晰，特征更加明显。灰度变换其实质就是按一定的规则修改图像每一个像素的...
• 这次我们要处理的是对图像进行旋转操作，具体要求，如下：  自定义一个图像的... 曾参考《数字图像处理（第三版）》一书中P51的公式编写过自己的图像“旋转”函数，但是在某些角度下，输出结果却发生了错误，至于
• 1、算法原理 分段线性拉伸算法是图像灰度变换中常用的算法，在商业图像编辑软件Photoshop中也有相应的功能。分段线性拉伸主要是用于提高图像对比度，突显图像细节。设输入图像为f(x)，输出图像为f'(x)，分段区间为...
• Java读入一张图，将其压缩至指定大小后转化为灰度图，然后对灰度图作直方图均衡和灰度拉伸，文末附代码。
• 灰度图像直方图均衡化公式及实现
• 灰度拉伸，与线性变换有点类似（可参考：灰度线性变换之c++实现（qt + 不调包）），不同之处在于灰度拉伸使用的是分段线性变换，所以它最大的优势是变换函数可以由用户任意合成。其公式如下图，其中x为输入像素值，...
• 常见的插值算法有最近邻插值算法，双线性插值算法，三次卷积等最近邻插值算法这是最简单的一种插值算法，根据目标图像（插值后的图像大小）与源图像大小的比值来寻找目标图像的像素位置对应于源图像像素的位置。...
• ## 图像灰度归一化

千次阅读 2019-12-05 18:05:14
cv::normalize(src, dst, 0, 255, NORMAL_MINMAX) 将灰度拉伸到0~255之间 cv::normalize(src, dst, 0, 1, NORMAL_MINMAX) 将灰度归一化到0~1之间
• % BitBum : BitBum : 灰度级 % mode : 模式：0:灰度图像 , 1:彩色图像 % History : 2021.xx.xx - 初次创建 % ************************************************************************* % 实现公式 ： F(i,j)原始...
• 一、图像灰度化处理1、最大值灰度处理方法2、平均灰度处理方法3、加权平均灰度处理方法二、图像灰度线性变换1、图像灰度上移变换2、图像对比度增强变换3、图像对比度减弱变换4、图像灰度反色变换三、图像灰度非线性...

...