影象灰度拉伸
阿新 • • 發佈:2018-12-11
影象灰度拉伸
文章目錄
1 原理
影象灰度拉伸是改變影象對比度的一種方法,通過灰度對映,將原圖中某一區段中的灰度值對映到另一灰度值,從而拉伸或壓縮整個影象的灰度分佈範圍。
2 Matlab實現
clc; clear; close all; % 對灰度圖進行灰度線性變換 ori_img = imread('../images/6.jpg'); 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; }